@turnkey/react-wallet-kit 1.7.2 → 1.8.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.
Files changed (33) hide show
  1. package/dist/components/import/Import.d.ts +2 -0
  2. package/dist/components/import/Import.d.ts.map +1 -1
  3. package/dist/components/import/Import.js +3 -2
  4. package/dist/components/import/Import.js.map +1 -1
  5. package/dist/components/import/Import.mjs +4 -3
  6. package/dist/components/import/Import.mjs.map +1 -1
  7. package/dist/providers/client/Provider.d.ts +1 -1
  8. package/dist/providers/client/Provider.d.ts.map +1 -1
  9. package/dist/providers/client/Provider.js +684 -880
  10. package/dist/providers/client/Provider.js.map +1 -1
  11. package/dist/providers/client/Provider.mjs +2329 -2494
  12. package/dist/providers/client/Provider.mjs.map +1 -1
  13. package/dist/providers/client/Types.d.ts +4 -0
  14. package/dist/providers/client/Types.d.ts.map +1 -1
  15. package/dist/providers/client/Types.js.map +1 -1
  16. package/dist/providers/client/Types.mjs.map +1 -1
  17. package/dist/tests/oauth-test.d.ts +2 -0
  18. package/dist/tests/oauth-test.d.ts.map +1 -0
  19. package/dist/types/method-types.d.ts +2 -0
  20. package/dist/types/method-types.d.ts.map +1 -1
  21. package/dist/utils/oauth.d.ts +323 -0
  22. package/dist/utils/oauth.d.ts.map +1 -0
  23. package/dist/utils/oauth.js +613 -0
  24. package/dist/utils/oauth.js.map +1 -0
  25. package/dist/utils/oauth.mjs +670 -0
  26. package/dist/utils/oauth.mjs.map +1 -0
  27. package/dist/utils/utils.d.ts +1 -41
  28. package/dist/utils/utils.d.ts.map +1 -1
  29. package/dist/utils/utils.js +0 -161
  30. package/dist/utils/utils.js.map +1 -1
  31. package/dist/utils/utils.mjs +2 -216
  32. package/dist/utils/utils.mjs.map +1 -1
  33. package/package.json +4 -4
@@ -0,0 +1,670 @@
1
+ import { defineProperty as _defineProperty, createForOfIteratorHelper as _createForOfIteratorHelper, slicedToArray as _slicedToArray, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator, toConsumableArray as _toConsumableArray, objectSpread2 as _objectSpread2 } from '../_virtual/_rollupPluginBabelHelpers.mjs';
2
+ import { OAuthProviders, TurnkeyError, TurnkeyErrorCodes } from '@turnkey/sdk-types';
3
+ import { faGoogle, faApple, faXTwitter, faDiscord, faFacebook } from '@fortawesome/free-brands-svg-icons';
4
+
5
+ // ============================================================================
6
+ // OAuth URL Constants
7
+ // ============================================================================
8
+ var DISCORD_AUTH_URL = "https://discord.com/oauth2/authorize";
9
+ var X_AUTH_URL = "https://x.com/i/oauth2/authorize";
10
+ var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
11
+ var APPLE_AUTH_URL = "https://account.apple.com/auth/authorize";
12
+ var FACEBOOK_AUTH_URL = "https://www.facebook.com/v11.0/dialog/oauth";
13
+ var FACEBOOK_GRAPH_URL = "https://graph.facebook.com/v11.0/oauth/access_token";
14
+ // ============================================================================
15
+ // OAuth Popup Constants
16
+ // ============================================================================
17
+ var popupWidth = 500;
18
+ var popupHeight = 600;
19
+ // ============================================================================
20
+ // OAuth Intent Constants
21
+ // ============================================================================
22
+ var OAUTH_INTENT_ADD_PROVIDER = "addProvider";
23
+ var OAUTH_ADD_PROVIDER_METADATA_KEY = "oauth_add_provider_metadata";
24
+ /**
25
+ * Stores OAuth add provider metadata in session storage
26
+ * Used for addOauthProvider flow if opening in-page
27
+ */
28
+ function storeOAuthAddProviderMetadata(metadata) {
29
+ try {
30
+ sessionStorage.setItem(OAUTH_ADD_PROVIDER_METADATA_KEY, JSON.stringify(metadata));
31
+ } catch (error) {
32
+ throw new TurnkeyError("Failed to store OAuth add provider metadata: ".concat(error instanceof Error ? error.message : "Unknown error"), TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR);
33
+ }
34
+ }
35
+ /**
36
+ * Retrieves OAuth add provider metadata from session storage
37
+ */
38
+ function getOAuthAddProviderMetadata() {
39
+ try {
40
+ var stored = sessionStorage.getItem(OAUTH_ADD_PROVIDER_METADATA_KEY);
41
+ if (!stored) return null;
42
+ try {
43
+ return JSON.parse(stored);
44
+ } catch (_unused) {
45
+ return null;
46
+ }
47
+ } catch (error) {
48
+ throw new TurnkeyError("Failed to retrieve OAuth add provider metadata: ".concat(error instanceof Error ? error.message : "Unknown error"), TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR);
49
+ }
50
+ }
51
+ /**
52
+ * Clears OAuth add provider metadata from session storage
53
+ */
54
+ function clearOAuthAddProviderMetadata() {
55
+ try {
56
+ sessionStorage.removeItem(OAUTH_ADD_PROVIDER_METADATA_KEY);
57
+ } catch (error) {
58
+ throw new TurnkeyError("Failed to clear OAuth add provider metadata: ".concat(error instanceof Error ? error.message : "Unknown error"), TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR);
59
+ }
60
+ }
61
+ // ============================================================================
62
+ // OAuth State Building
63
+ // ============================================================================
64
+ /**
65
+ * Builds the OAuth state parameter string
66
+ */
67
+ function buildOAuthState(params) {
68
+ var provider = params.provider,
69
+ flow = params.flow,
70
+ publicKey = params.publicKey,
71
+ nonce = params.nonce,
72
+ additionalState = params.additionalState;
73
+ var state = "provider=".concat(provider, "&flow=").concat(flow, "&publicKey=").concat(encodeURIComponent(publicKey));
74
+ if (nonce) {
75
+ state += "&nonce=".concat(nonce);
76
+ }
77
+ if (additionalState) {
78
+ var extra = Object.entries(additionalState).map(function (_ref) {
79
+ var _ref2 = _slicedToArray(_ref, 2),
80
+ k = _ref2[0],
81
+ v = _ref2[1];
82
+ return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v));
83
+ }).join("&");
84
+ if (extra) {
85
+ state += "&".concat(extra);
86
+ }
87
+ }
88
+ return state;
89
+ }
90
+ // ============================================================================
91
+ // OAuth Provider Opening Utilities
92
+ // ============================================================================
93
+ /**
94
+ * Opens a centered OAuth popup window
95
+ */
96
+ function openOAuthPopup() {
97
+ var width = popupWidth;
98
+ var height = popupHeight;
99
+ var left = window.screenX + (window.innerWidth - width) / 2;
100
+ var top = window.screenY + (window.innerHeight - height) / 2;
101
+ return window.open("about:blank", "_blank", "width=".concat(width, ",height=").concat(height, ",top=").concat(top, ",left=").concat(left, ",scrollbars=yes,resizable=yes"));
102
+ }
103
+ /**
104
+ * Redirects to OAuth provider URL
105
+ */
106
+ function redirectToOAuthProvider(url) {
107
+ window.location.href = url;
108
+ var timeLimit = 5 * 60 * 1000; // 5 minutes
109
+ return new Promise(function (_, reject) {
110
+ var timeout = setTimeout(function () {
111
+ reject(new Error("Authentication timed out."));
112
+ }, timeLimit);
113
+ window.addEventListener("beforeunload", function () {
114
+ return clearTimeout(timeout);
115
+ });
116
+ });
117
+ }
118
+ // ============================================================================
119
+ // OAuth URL Cleanup
120
+ // ============================================================================
121
+ /**
122
+ * Cleans up OAuth parameters from URL (removes hash and search)
123
+ */
124
+ function cleanupOAuthUrl() {
125
+ window.history.replaceState(null, document.title, window.location.pathname);
126
+ }
127
+ /**
128
+ * Cleans up OAuth hash from URL but preserves search parameters
129
+ */
130
+ function cleanupOAuthUrlPreserveSearch() {
131
+ window.history.replaceState(null, document.title, window.location.pathname + window.location.search);
132
+ }
133
+ // ============================================================================
134
+ // OAuth State Parsing
135
+ // ============================================================================
136
+ /**
137
+ * Parses the OAuth state parameter string into an object
138
+ */
139
+ function parseStateParam(stateParam) {
140
+ if (!stateParam) return {};
141
+ var result = {};
142
+ var pairs = stateParam.split("&");
143
+ var _iterator = _createForOfIteratorHelper(pairs),
144
+ _step;
145
+ try {
146
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
147
+ var pair = _step.value;
148
+ var _pair$split = pair.split("="),
149
+ _pair$split2 = _slicedToArray(_pair$split, 2),
150
+ key = _pair$split2[0],
151
+ value = _pair$split2[1];
152
+ if (key && value !== undefined) {
153
+ result[key] = decodeURIComponent(value);
154
+ }
155
+ }
156
+ } catch (err) {
157
+ _iterator.e(err);
158
+ } finally {
159
+ _iterator.f();
160
+ }
161
+ return result;
162
+ }
163
+ /**
164
+ * Unified OAuth response parser for both popup and redirect flows.
165
+ * Handles both:
166
+ * - PKCE flows (Facebook, Discord, X): code in search parameters
167
+ * - Non-PKCE flows (Google, Apple): id_token in hash parameters
168
+ * - Apple's non-standard hash format where state parameters are directly embedded
169
+ *
170
+ * @param url - The full URL to parse (from popup or redirect)
171
+ * @param expectedProvider - Optional provider if already known (for popup flows)
172
+ * @returns Parsed OAuth response data including tokens, codes, and state parameters, or null if invalid
173
+ */
174
+ function parseOAuthResponse(url, expectedProvider) {
175
+ var idToken = null;
176
+ var authCode = null;
177
+ var stateString = null;
178
+ var parsedUrl = new URL(url);
179
+ var search = parsedUrl.search.substring(1); // Remove leading '?'
180
+ var hash = parsedUrl.hash.substring(1); // Remove leading '#'
181
+ // Handle PKCE flows (code in search parameters)
182
+ if (search && search.includes("code=")) {
183
+ var searchParams = new URLSearchParams(search);
184
+ authCode = searchParams.get("code");
185
+ stateString = searchParams.get("state");
186
+ }
187
+ // Handle non-PKCE flows (id_token in hash)
188
+ else if (hash) {
189
+ // Handle Apple's non-standard format: state=provider=apple&flow=redirect&...&code=...&id_token=...
190
+ if (hash.startsWith("state=provider=apple")) {
191
+ // Extract id_token from the end
192
+ var idTokenMatch = hash.match(/id_token=([^&]+)$/);
193
+ idToken = idTokenMatch ? idTokenMatch[1] : null;
194
+ // Extract state content between "state=" and "&code="
195
+ var stateEndIndex = hash.indexOf("&code=");
196
+ if (stateEndIndex !== -1) {
197
+ stateString = hash.substring(6, stateEndIndex); // Remove "state=" prefix
198
+ }
199
+ } else {
200
+ // Standard OAuth format - parse as URLSearchParams
201
+ var hashParams = new URLSearchParams(hash);
202
+ idToken = hashParams.get("id_token");
203
+ stateString = hashParams.get("state");
204
+ }
205
+ }
206
+ // Parse state parameters
207
+ var _parseStateParam = parseStateParam(stateString),
208
+ provider = _parseStateParam.provider,
209
+ flow = _parseStateParam.flow,
210
+ publicKey = _parseStateParam.publicKey,
211
+ openModal = _parseStateParam.openModal,
212
+ sessionKey = _parseStateParam.sessionKey,
213
+ oauthIntent = _parseStateParam.oauthIntent,
214
+ nonce = _parseStateParam.nonce;
215
+ // If we have an expected provider (popup flow), validate it matches
216
+ if (expectedProvider) {
217
+ var config = OAUTH_PROVIDER_CONFIGS[expectedProvider];
218
+ if (config.usesPKCE) {
219
+ // PKCE providers must have authCode and matching provider in state
220
+ if (!authCode || !stateString || provider !== expectedProvider) {
221
+ return null;
222
+ }
223
+ } else {
224
+ // Non-PKCE providers must have idToken
225
+ if (!idToken) {
226
+ return null;
227
+ }
228
+ }
229
+ }
230
+ return {
231
+ idToken: idToken,
232
+ authCode: authCode,
233
+ provider: provider !== null && provider !== void 0 ? provider : null,
234
+ flow: flow !== null && flow !== void 0 ? flow : null,
235
+ publicKey: publicKey !== null && publicKey !== void 0 ? publicKey : null,
236
+ openModal: openModal !== null && openModal !== void 0 ? openModal : null,
237
+ sessionKey: sessionKey !== null && sessionKey !== void 0 ? sessionKey : undefined,
238
+ oauthIntent: oauthIntent !== null && oauthIntent !== void 0 ? oauthIntent : null,
239
+ nonce: nonce !== null && nonce !== void 0 ? nonce : null
240
+ };
241
+ }
242
+ // ============================================================================
243
+ // PKCE Utilities
244
+ // ============================================================================
245
+ /**
246
+ * Generates a PKCE challenge pair (verifier and code challenge)
247
+ */
248
+ function generateChallengePair() {
249
+ return _generateChallengePair.apply(this, arguments);
250
+ }
251
+ /**
252
+ * Exchanges Facebook authorization code for token
253
+ */
254
+ function _generateChallengePair() {
255
+ _generateChallengePair = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
256
+ var randomBytes, verifier, encoder, data, digest, base64Challenge;
257
+ return _regenerator().w(function (_context) {
258
+ while (1) switch (_context.n) {
259
+ case 0:
260
+ randomBytes = new Uint8Array(32);
261
+ window.crypto.getRandomValues(randomBytes);
262
+ verifier = btoa(String.fromCharCode.apply(String, _toConsumableArray(randomBytes))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
263
+ encoder = new TextEncoder();
264
+ data = encoder.encode(verifier);
265
+ _context.n = 1;
266
+ return window.crypto.subtle.digest("SHA-256", data);
267
+ case 1:
268
+ digest = _context.v;
269
+ base64Challenge = btoa(String.fromCharCode.apply(String, _toConsumableArray(new Uint8Array(digest)))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
270
+ return _context.a(2, {
271
+ verifier: verifier,
272
+ codeChallenge: base64Challenge
273
+ });
274
+ }
275
+ }, _callee);
276
+ }));
277
+ return _generateChallengePair.apply(this, arguments);
278
+ }
279
+ function exchangeFacebookCodeForToken(_x, _x2, _x3, _x4) {
280
+ return _exchangeFacebookCodeForToken.apply(this, arguments);
281
+ }
282
+ /**
283
+ * Unified OAuth completion handler.
284
+ * Routes to the appropriate completion handler based on params:
285
+ * Priority: onAddProvider > onOauthSuccess > callbacks.onOauthRedirect > completeOauth
286
+ *
287
+ * This is the core completion logic used by both popup and redirect flows.
288
+ */
289
+ function _exchangeFacebookCodeForToken() {
290
+ _exchangeFacebookCodeForToken = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(clientId, redirectUri, code, codeVerifier) {
291
+ var params, response, errorData;
292
+ return _regenerator().w(function (_context2) {
293
+ while (1) switch (_context2.n) {
294
+ case 0:
295
+ params = new URLSearchParams({
296
+ client_id: clientId,
297
+ redirect_uri: redirectUri,
298
+ code_verifier: codeVerifier,
299
+ code: code,
300
+ grant_type: "authorization_code"
301
+ });
302
+ _context2.n = 1;
303
+ return fetch(FACEBOOK_GRAPH_URL, {
304
+ method: "POST",
305
+ headers: {
306
+ "Content-Type": "application/x-www-form-urlencoded"
307
+ },
308
+ body: params.toString()
309
+ });
310
+ case 1:
311
+ response = _context2.v;
312
+ if (response.ok) {
313
+ _context2.n = 3;
314
+ break;
315
+ }
316
+ _context2.n = 2;
317
+ return response.json();
318
+ case 2:
319
+ errorData = _context2.v;
320
+ throw new Error("Facebook token exchange failed: ".concat(JSON.stringify(errorData)));
321
+ case 3:
322
+ _context2.n = 4;
323
+ return response.json();
324
+ case 4:
325
+ return _context2.a(2, _context2.v);
326
+ }
327
+ }, _callee2);
328
+ }));
329
+ return _exchangeFacebookCodeForToken.apply(this, arguments);
330
+ }
331
+ function completeOAuthFlow(_x5) {
332
+ return _completeOAuthFlow.apply(this, arguments);
333
+ }
334
+ /**
335
+ * Gets the verifier key name for a PKCE provider
336
+ */
337
+ function _completeOAuthFlow() {
338
+ _completeOAuthFlow = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(params) {
339
+ var provider, publicKey, oidcToken, sessionKey, callbacks, completeOauth, onOauthSuccess, onAddProvider;
340
+ return _regenerator().w(function (_context3) {
341
+ while (1) switch (_context3.n) {
342
+ case 0:
343
+ provider = params.provider, publicKey = params.publicKey, oidcToken = params.oidcToken, sessionKey = params.sessionKey, callbacks = params.callbacks, completeOauth = params.completeOauth, onOauthSuccess = params.onOauthSuccess, onAddProvider = params.onAddProvider;
344
+ if (!onAddProvider) {
345
+ _context3.n = 2;
346
+ break;
347
+ }
348
+ _context3.n = 1;
349
+ return onAddProvider(oidcToken);
350
+ case 1:
351
+ _context3.n = 5;
352
+ break;
353
+ case 2:
354
+ if (!onOauthSuccess) {
355
+ _context3.n = 3;
356
+ break;
357
+ }
358
+ onOauthSuccess(_objectSpread2({
359
+ publicKey: publicKey,
360
+ oidcToken: oidcToken,
361
+ providerName: provider
362
+ }, sessionKey && {
363
+ sessionKey: sessionKey
364
+ }));
365
+ _context3.n = 5;
366
+ break;
367
+ case 3:
368
+ if (!(callbacks !== null && callbacks !== void 0 && callbacks.onOauthRedirect)) {
369
+ _context3.n = 4;
370
+ break;
371
+ }
372
+ callbacks.onOauthRedirect(_objectSpread2({
373
+ idToken: oidcToken,
374
+ publicKey: publicKey
375
+ }, sessionKey && {
376
+ sessionKey: sessionKey
377
+ }));
378
+ _context3.n = 5;
379
+ break;
380
+ case 4:
381
+ _context3.n = 5;
382
+ return completeOauth(_objectSpread2({
383
+ oidcToken: oidcToken,
384
+ publicKey: publicKey,
385
+ providerName: provider
386
+ }, sessionKey && {
387
+ sessionKey: sessionKey
388
+ }));
389
+ case 5:
390
+ return _context3.a(2);
391
+ }
392
+ }, _callee3);
393
+ }));
394
+ return _completeOAuthFlow.apply(this, arguments);
395
+ }
396
+ function getPKCEVerifierKey(provider) {
397
+ return "".concat(provider, "_verifier");
398
+ }
399
+ /**
400
+ * Retrieves and removes the PKCE verifier from session storage
401
+ * @param provider - The OAuth provider
402
+ * @returns The verifier string
403
+ * @throws TurnkeyError if verifier is not found
404
+ */
405
+ function consumePKCEVerifier(provider) {
406
+ try {
407
+ var key = getPKCEVerifierKey(provider);
408
+ var verifier = sessionStorage.getItem(key);
409
+ if (!verifier) {
410
+ throw new TurnkeyError("Missing PKCE verifier for ".concat(provider, " authentication"), TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR);
411
+ }
412
+ sessionStorage.removeItem(key);
413
+ return verifier;
414
+ } catch (error) {
415
+ if (error instanceof TurnkeyError) {
416
+ throw error;
417
+ }
418
+ throw new TurnkeyError("Failed to access PKCE verifier for ".concat(provider, ": ").concat(error instanceof Error ? error.message : "Unknown error"), TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR);
419
+ }
420
+ }
421
+ /**
422
+ * Stores the PKCE verifier in session storage
423
+ * @param provider - The OAuth provider
424
+ * @param verifier - The verifier string to store
425
+ */
426
+ function storePKCEVerifier(provider, verifier) {
427
+ try {
428
+ sessionStorage.setItem(getPKCEVerifierKey(provider), verifier);
429
+ } catch (error) {
430
+ throw new TurnkeyError("Failed to store PKCE verifier for ".concat(provider, ": ").concat(error instanceof Error ? error.message : "Unknown error"), TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR);
431
+ }
432
+ }
433
+ /**
434
+ * Checks if a PKCE verifier exists for a provider (without consuming it)
435
+ * @param provider - The OAuth provider
436
+ * @returns true if verifier exists
437
+ */
438
+ function hasPKCEVerifier(provider) {
439
+ try {
440
+ return sessionStorage.getItem(getPKCEVerifierKey(provider)) !== null;
441
+ } catch (error) {
442
+ throw new TurnkeyError("Failed to check PKCE verifier for ".concat(provider, ": ").concat(error instanceof Error ? error.message : "Unknown error"), TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR);
443
+ }
444
+ }
445
+ /**
446
+ * Unified PKCE flow handler for all PKCE-based OAuth providers.
447
+ * Handles the complete PKCE flow: verifier retrieval, token exchange, and completion routing.
448
+ *
449
+ * This function abstracts the common logic shared between popup and redirect flows
450
+ * for Facebook, Discord, and Twitter/X.
451
+ *
452
+ * @param params - The PKCE flow parameters
453
+ * @returns A promise that resolves when the flow is complete
454
+ */
455
+ function handlePKCEFlow(_x6) {
456
+ return _handlePKCEFlow.apply(this, arguments);
457
+ }
458
+ /**
459
+ * Pre-configured OAuth provider settings
460
+ */
461
+ function _handlePKCEFlow() {
462
+ _handlePKCEFlow = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(_ref3) {
463
+ var publicKey, providerName, sessionKey, callbacks, completeOauth, onOauthSuccess, onAddProvider, exchangeCodeForToken, verifier, oidcToken;
464
+ return _regenerator().w(function (_context4) {
465
+ while (1) switch (_context4.n) {
466
+ case 0:
467
+ publicKey = _ref3.publicKey, providerName = _ref3.providerName, sessionKey = _ref3.sessionKey, callbacks = _ref3.callbacks, completeOauth = _ref3.completeOauth, onOauthSuccess = _ref3.onOauthSuccess, onAddProvider = _ref3.onAddProvider, exchangeCodeForToken = _ref3.exchangeCodeForToken;
468
+ // Consume the verifier (retrieves and removes from storage)
469
+ verifier = consumePKCEVerifier(providerName); // Exchange the code for an OIDC token using the provider-specific function
470
+ _context4.n = 1;
471
+ return exchangeCodeForToken(verifier);
472
+ case 1:
473
+ oidcToken = _context4.v;
474
+ _context4.n = 2;
475
+ return completeOAuthFlow({
476
+ provider: providerName,
477
+ publicKey: publicKey,
478
+ oidcToken: oidcToken,
479
+ sessionKey: sessionKey,
480
+ callbacks: callbacks,
481
+ completeOauth: completeOauth,
482
+ onOauthSuccess: onOauthSuccess,
483
+ onAddProvider: onAddProvider
484
+ });
485
+ case 2:
486
+ return _context4.a(2);
487
+ }
488
+ }, _callee4);
489
+ }));
490
+ return _handlePKCEFlow.apply(this, arguments);
491
+ }
492
+ var OAUTH_PROVIDER_CONFIGS = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, OAuthProviders.GOOGLE, {
493
+ provider: OAuthProviders.GOOGLE,
494
+ authUrl: GOOGLE_AUTH_URL,
495
+ scopes: "openid email profile",
496
+ usesPKCE: false,
497
+ responseType: "id_token",
498
+ nonceInParams: true
499
+ }), OAuthProviders.APPLE, {
500
+ provider: OAuthProviders.APPLE,
501
+ authUrl: APPLE_AUTH_URL,
502
+ scopes: "",
503
+ usesPKCE: false,
504
+ responseType: "code id_token",
505
+ responseMode: "fragment",
506
+ nonceInParams: true
507
+ }), OAuthProviders.FACEBOOK, {
508
+ provider: OAuthProviders.FACEBOOK,
509
+ authUrl: FACEBOOK_AUTH_URL,
510
+ scopes: "openid",
511
+ usesPKCE: true,
512
+ responseType: "code",
513
+ nonceInParams: true
514
+ }), OAuthProviders.DISCORD, {
515
+ provider: OAuthProviders.DISCORD,
516
+ authUrl: DISCORD_AUTH_URL,
517
+ scopes: "identify email",
518
+ usesPKCE: true,
519
+ responseType: "code",
520
+ nonceInParams: false
521
+ }), OAuthProviders.X, {
522
+ provider: OAuthProviders.X,
523
+ authUrl: X_AUTH_URL,
524
+ scopes: "tweet.read users.read",
525
+ usesPKCE: true,
526
+ responseType: "code",
527
+ nonceInParams: false
528
+ });
529
+ /**
530
+ * Builds the complete OAuth authorization URL for a provider
531
+ */
532
+ function buildOAuthUrl(params) {
533
+ var provider = params.provider,
534
+ clientId = params.clientId,
535
+ redirectUri = params.redirectUri,
536
+ publicKey = params.publicKey,
537
+ nonce = params.nonce,
538
+ flow = params.flow,
539
+ codeChallenge = params.codeChallenge,
540
+ additionalState = params.additionalState;
541
+ var config = OAUTH_PROVIDER_CONFIGS[provider];
542
+ var authUrl = new URL(config.authUrl);
543
+ authUrl.searchParams.set("client_id", clientId);
544
+ authUrl.searchParams.set("redirect_uri", redirectUri);
545
+ authUrl.searchParams.set("response_type", config.responseType);
546
+ if (config.scopes) {
547
+ authUrl.searchParams.set("scope", config.scopes);
548
+ }
549
+ if (config.responseMode) {
550
+ authUrl.searchParams.set("response_mode", config.responseMode);
551
+ }
552
+ // PKCE parameters
553
+ if (config.usesPKCE && codeChallenge) {
554
+ authUrl.searchParams.set("code_challenge", codeChallenge);
555
+ authUrl.searchParams.set("code_challenge_method", "S256");
556
+ }
557
+ // Nonce handling - some providers want it in URL params, others in state
558
+ if (config.nonceInParams) {
559
+ authUrl.searchParams.set("nonce", nonce);
560
+ }
561
+ // Google-specific: prompt for account selection
562
+ if (provider === OAuthProviders.GOOGLE) {
563
+ authUrl.searchParams.set("prompt", "select_account");
564
+ }
565
+ // Build state parameter
566
+ var stateParams = {
567
+ provider: provider,
568
+ flow: flow,
569
+ publicKey: publicKey
570
+ };
571
+ // Include nonce in state for providers that need it there (not in URL params)
572
+ if (!config.nonceInParams) {
573
+ stateParams.nonce = nonce;
574
+ }
575
+ if (additionalState) {
576
+ stateParams.additionalState = additionalState;
577
+ }
578
+ authUrl.searchParams.set("state", buildOAuthState(stateParams));
579
+ return authUrl.toString();
580
+ }
581
+ /**
582
+ * Completes OAuth flow in popup - handles both PKCE and non-PKCE providers
583
+ */
584
+ function completeOAuthPopup(_x7) {
585
+ return _completeOAuthPopup.apply(this, arguments);
586
+ }
587
+ // ============================================================================
588
+ // OAuth Helper Utilities
589
+ // ============================================================================
590
+ /**
591
+ * Capitalizes the first letter of a provider name
592
+ * @param provider - The provider name (e.g., "facebook", "discord")
593
+ * @returns The capitalized provider name (e.g., "Facebook", "Discord")
594
+ */
595
+ function _completeOAuthPopup() {
596
+ _completeOAuthPopup = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(params) {
597
+ var provider, publicKey, result, callbacks, completeOauth, onOauthSuccess, exchangeCodeForToken, config;
598
+ return _regenerator().w(function (_context5) {
599
+ while (1) switch (_context5.n) {
600
+ case 0:
601
+ provider = params.provider, publicKey = params.publicKey, result = params.result, callbacks = params.callbacks, completeOauth = params.completeOauth, onOauthSuccess = params.onOauthSuccess, exchangeCodeForToken = params.exchangeCodeForToken;
602
+ config = OAUTH_PROVIDER_CONFIGS[provider];
603
+ if (!config.usesPKCE) {
604
+ _context5.n = 3;
605
+ break;
606
+ }
607
+ if (exchangeCodeForToken) {
608
+ _context5.n = 1;
609
+ break;
610
+ }
611
+ throw new TurnkeyError("exchangeCodeForToken is required for PKCE providers", TurnkeyErrorCodes.INTERNAL_ERROR);
612
+ case 1:
613
+ _context5.n = 2;
614
+ return handlePKCEFlow({
615
+ publicKey: publicKey,
616
+ providerName: provider,
617
+ sessionKey: result.sessionKey,
618
+ callbacks: callbacks,
619
+ completeOauth: completeOauth,
620
+ onOauthSuccess: onOauthSuccess,
621
+ exchangeCodeForToken: exchangeCodeForToken
622
+ });
623
+ case 2:
624
+ _context5.n = 4;
625
+ break;
626
+ case 3:
627
+ _context5.n = 4;
628
+ return completeOAuthFlow({
629
+ provider: provider,
630
+ publicKey: publicKey,
631
+ oidcToken: result.idToken,
632
+ sessionKey: result.sessionKey,
633
+ callbacks: callbacks,
634
+ completeOauth: completeOauth,
635
+ onOauthSuccess: onOauthSuccess
636
+ });
637
+ case 4:
638
+ return _context5.a(2);
639
+ }
640
+ }, _callee5);
641
+ }));
642
+ return _completeOAuthPopup.apply(this, arguments);
643
+ }
644
+ function capitalizeProviderName(provider) {
645
+ if (!provider) return "Provider";
646
+ return provider.charAt(0).toUpperCase() + provider.slice(1);
647
+ }
648
+ /**
649
+ * Gets the FontAwesome icon for an OAuth provider
650
+ * @param provider - The provider name
651
+ * @returns The FontAwesome icon definition
652
+ */
653
+ function getProviderIcon(provider) {
654
+ switch (provider) {
655
+ case OAuthProviders.FACEBOOK:
656
+ return faFacebook;
657
+ case OAuthProviders.DISCORD:
658
+ return faDiscord;
659
+ case OAuthProviders.X:
660
+ return faXTwitter;
661
+ case OAuthProviders.APPLE:
662
+ return faApple;
663
+ case OAuthProviders.GOOGLE:
664
+ default:
665
+ return faGoogle;
666
+ }
667
+ }
668
+
669
+ export { APPLE_AUTH_URL, DISCORD_AUTH_URL, FACEBOOK_AUTH_URL, FACEBOOK_GRAPH_URL, GOOGLE_AUTH_URL, OAUTH_ADD_PROVIDER_METADATA_KEY, OAUTH_INTENT_ADD_PROVIDER, OAUTH_PROVIDER_CONFIGS, X_AUTH_URL, buildOAuthState, buildOAuthUrl, capitalizeProviderName, cleanupOAuthUrl, cleanupOAuthUrlPreserveSearch, clearOAuthAddProviderMetadata, completeOAuthFlow, completeOAuthPopup, consumePKCEVerifier, exchangeFacebookCodeForToken, generateChallengePair, getOAuthAddProviderMetadata, getPKCEVerifierKey, getProviderIcon, handlePKCEFlow, hasPKCEVerifier, openOAuthPopup, parseOAuthResponse, parseStateParam, popupHeight, popupWidth, redirectToOAuthProvider, storeOAuthAddProviderMetadata, storePKCEVerifier };
670
+ //# sourceMappingURL=oauth.mjs.map