@cimplify/sdk 0.67.0 → 0.68.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 (40) hide show
  1. package/dist/advanced.d.mts +1 -1
  2. package/dist/advanced.d.ts +1 -1
  3. package/dist/advanced.js +20 -20
  4. package/dist/advanced.mjs +1 -1
  5. package/dist/{chunk-SSLFZPAI.js → chunk-5HAUJBOK.js} +35 -35
  6. package/dist/{chunk-JAPCAZN4.mjs → chunk-KNPE4WCQ.mjs} +1 -1
  7. package/dist/{chunk-SH6HJW4A.js → chunk-NGQCWFKF.js} +2 -2
  8. package/dist/{chunk-QQMDEGAK.mjs → chunk-SOV4H6PQ.mjs} +177 -50
  9. package/dist/{chunk-FNK6UZOE.mjs → chunk-TAKORJP4.mjs} +1 -1
  10. package/dist/{chunk-3QSW33RG.js → chunk-WCSAZRNC.js} +179 -49
  11. package/dist/{client-Dd82KQ_G.d.mts → client-CBE7ksYC.d.mts} +1 -1
  12. package/dist/{client-DVFQoDtI.d.ts → client-CfeQRwhl.d.ts} +24 -2
  13. package/dist/{client-CQlEWH5j.d.ts → client-DlXfZy7N.d.ts} +1 -1
  14. package/dist/{client-ByI_3jfL.d.mts → client-Dyo3dvNy.d.mts} +24 -2
  15. package/dist/index.d.mts +2 -2
  16. package/dist/index.d.ts +2 -2
  17. package/dist/index.js +89 -72
  18. package/dist/index.mjs +15 -10
  19. package/dist/react.d.mts +43 -40
  20. package/dist/react.d.ts +43 -40
  21. package/dist/react.js +251 -120
  22. package/dist/react.mjs +237 -106
  23. package/dist/server.d.mts +2 -2
  24. package/dist/server.d.ts +2 -2
  25. package/dist/server.js +7 -7
  26. package/dist/server.mjs +2 -2
  27. package/dist/{sign-in-RFuWZOgF.d.mts → sign-in-DQlIdqsi.d.mts} +8 -0
  28. package/dist/{sign-in-RFuWZOgF.d.ts → sign-in-DQlIdqsi.d.ts} +8 -0
  29. package/dist/styles.css +1 -1
  30. package/dist/testing/suite.d.mts +2 -2
  31. package/dist/testing/suite.d.ts +2 -2
  32. package/dist/testing/suite.js +22 -22
  33. package/dist/testing/suite.mjs +3 -3
  34. package/dist/testing.d.mts +17 -17
  35. package/dist/testing.d.ts +17 -17
  36. package/dist/testing.js +78 -78
  37. package/dist/testing.mjs +4 -4
  38. package/package.json +1 -1
  39. package/registry/index.json +0 -9
  40. package/registry/account.json +0 -15
@@ -2270,6 +2270,17 @@ var MESSAGE_TYPES = {
2270
2270
  ORDER_TYPE_CHANGED: "order_type_changed",
2271
2271
  REQUEST_SUBMIT: "request_submit"
2272
2272
  };
2273
+ var ELEMENTS_AUTH_CONTACT_TYPES = {
2274
+ EMAIL: "email",
2275
+ PHONE: "phone"
2276
+ };
2277
+ var ELEMENTS_AUTH_PROMPTS = {
2278
+ LOGIN: "login"
2279
+ };
2280
+ var ELEMENTS_AUTH_MODES = {
2281
+ CHECKOUT: "checkout",
2282
+ DEFAULT: "default"
2283
+ };
2273
2284
  var EVENT_TYPES = {
2274
2285
  READY: "ready",
2275
2286
  AUTHENTICATED: "authenticated",
@@ -2404,6 +2415,119 @@ function openModalIframe(opts) {
2404
2415
 
2405
2416
  // src/sign-in.ts
2406
2417
  var DEFAULT_SCOPE = "openid email phone profile";
2418
+ var DEFAULT_SILENT_TIMEOUT_MS = 900;
2419
+ var RESPONSE_TYPE_CODE = "code";
2420
+ var RESPONSE_MODE_WEB_MESSAGE = "web_message";
2421
+ var RESPONSE_MODE_QUERY = "query";
2422
+ var PROMPT_NONE = "none";
2423
+ var AUTHORIZATION_RESPONSE_MESSAGE_TYPE = "authorization_response";
2424
+ var ERROR_STATE_MISMATCH = "state_mismatch";
2425
+ var ERROR_CALLBACK_FAILED = "callback_failed";
2426
+ var ERROR_CALLBACK_EXCEPTION = "callback_exception";
2427
+ var ERROR_CANCELLED = "cancelled";
2428
+ var ERROR_LOGIN_REQUIRED = "login_required";
2429
+ var ERROR_CONSENT_REQUIRED = "consent_required";
2430
+ var ERROR_INTERACTION_REQUIRED = "interaction_required";
2431
+ var INTERACTIVE_AUTH_ERRORS = /* @__PURE__ */ new Set([
2432
+ ERROR_LOGIN_REQUIRED,
2433
+ ERROR_CONSENT_REQUIRED,
2434
+ ERROR_INTERACTION_REQUIRED
2435
+ ]);
2436
+ function buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, urlOpts) {
2437
+ const params = new URLSearchParams({
2438
+ response_type: RESPONSE_TYPE_CODE,
2439
+ response_mode: urlOpts.responseMode,
2440
+ client_id: opts.clientId,
2441
+ redirect_uri: opts.redirectUri,
2442
+ scope: opts.scope ?? DEFAULT_SCOPE,
2443
+ state,
2444
+ code_challenge: pkce.challenge,
2445
+ code_challenge_method: pkce.method
2446
+ });
2447
+ if (opts.loginHint) params.set("login_hint", opts.loginHint);
2448
+ if (urlOpts.prompt) params.set("prompt", urlOpts.prompt);
2449
+ if (opts.uiMode) params.set("ui_mode", opts.uiMode);
2450
+ return `${authorizeEndpoint}?${params.toString()}`;
2451
+ }
2452
+ async function exchangeAuthorizationCode(callbackUri, pkce, state, code) {
2453
+ const res = await fetch(callbackUri, {
2454
+ method: "POST",
2455
+ credentials: "include",
2456
+ headers: { "Content-Type": "application/json" },
2457
+ body: JSON.stringify({ code, codeVerifier: pkce.verifier, state })
2458
+ });
2459
+ if (!res.ok) {
2460
+ const body = await res.text().catch(() => "");
2461
+ throw { error: ERROR_CALLBACK_FAILED, description: body };
2462
+ }
2463
+ const payload = await res.json().catch(() => ({}));
2464
+ return {
2465
+ accessToken: payload.accessToken ?? payload.access_token,
2466
+ expiresIn: payload.expiresIn ?? payload.expires_in,
2467
+ scope: payload.scope
2468
+ };
2469
+ }
2470
+ async function trySilentModalSignIn(opts, authorizeEndpoint, callbackUri, pkce, state) {
2471
+ const expectedOrigin = new URL(authorizeEndpoint).origin;
2472
+ const iframe = document.createElement("iframe");
2473
+ iframe.style.display = "none";
2474
+ iframe.setAttribute("aria-hidden", "true");
2475
+ iframe.setAttribute("sandbox", "allow-scripts allow-same-origin");
2476
+ iframe.src = buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
2477
+ responseMode: RESPONSE_MODE_WEB_MESSAGE,
2478
+ prompt: PROMPT_NONE
2479
+ });
2480
+ return new Promise((resolve) => {
2481
+ let settled = false;
2482
+ let handler = () => {
2483
+ };
2484
+ const timeout = setTimeout(() => finish(false), opts.silentTimeoutMs ?? DEFAULT_SILENT_TIMEOUT_MS);
2485
+ const cleanup = () => {
2486
+ window.removeEventListener("message", handler);
2487
+ iframe.remove();
2488
+ clearTimeout(timeout);
2489
+ };
2490
+ const finish = (handled) => {
2491
+ if (settled) return;
2492
+ settled = true;
2493
+ cleanup();
2494
+ resolve(handled);
2495
+ };
2496
+ handler = async (event) => {
2497
+ if (event.origin !== expectedOrigin) return;
2498
+ const data = event.data;
2499
+ if (!data || typeof data !== "object" || data.type !== AUTHORIZATION_RESPONSE_MESSAGE_TYPE) return;
2500
+ const response = data.response;
2501
+ if (response.error) {
2502
+ if (INTERACTIVE_AUTH_ERRORS.has(response.error)) {
2503
+ finish(false);
2504
+ return;
2505
+ }
2506
+ opts.onError?.({ error: response.error, description: response.error_description });
2507
+ finish(true);
2508
+ return;
2509
+ }
2510
+ if (!response.code) return;
2511
+ if (response.state !== state) {
2512
+ opts.onError?.({ error: ERROR_STATE_MISMATCH });
2513
+ finish(true);
2514
+ return;
2515
+ }
2516
+ try {
2517
+ opts.onSuccess?.(await exchangeAuthorizationCode(callbackUri, pkce, state, response.code));
2518
+ } catch (e) {
2519
+ const err2 = e;
2520
+ opts.onError?.({
2521
+ error: err2.error ?? ERROR_CALLBACK_EXCEPTION,
2522
+ description: err2.description ?? String(e)
2523
+ });
2524
+ }
2525
+ finish(true);
2526
+ };
2527
+ window.addEventListener("message", handler);
2528
+ document.body.appendChild(iframe);
2529
+ });
2530
+ }
2407
2531
  function resolveAuthorizeEndpoint(opts) {
2408
2532
  if (opts.authUrl) {
2409
2533
  return Promise.resolve(`${opts.authUrl.replace(/\/$/, "")}/oauth/authorize`);
@@ -2419,64 +2543,59 @@ async function startSignIn(opts) {
2419
2543
  startRedirectSignIn(opts, authorizeEndpoint, pkce, state);
2420
2544
  return;
2421
2545
  }
2422
- const params = new URLSearchParams({
2423
- response_type: "code",
2424
- response_mode: "web_message",
2425
- client_id: opts.clientId,
2426
- redirect_uri: opts.redirectUri,
2427
- scope: opts.scope ?? DEFAULT_SCOPE,
2428
- state,
2429
- code_challenge: pkce.challenge,
2430
- code_challenge_method: pkce.method
2546
+ if (opts.silentFirst && !opts.prompt) {
2547
+ const handledSilently = await trySilentModalSignIn(opts, authorizeEndpoint, callbackUri, pkce, state);
2548
+ if (handledSilently) {
2549
+ return;
2550
+ }
2551
+ }
2552
+ const src = buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
2553
+ responseMode: RESPONSE_MODE_WEB_MESSAGE,
2554
+ prompt: opts.prompt
2431
2555
  });
2432
- if (opts.loginHint) params.set("login_hint", opts.loginHint);
2433
- if (opts.prompt) params.set("prompt", opts.prompt);
2434
- const src = `${authorizeEndpoint}?${params.toString()}`;
2435
2556
  const expectedOrigin = new URL(authorizeEndpoint).origin;
2557
+ let completed = false;
2558
+ let handler = () => {
2559
+ };
2436
2560
  const modal = openModalIframe({
2437
2561
  src,
2438
2562
  onClose: () => {
2439
2563
  window.removeEventListener("message", handler);
2564
+ if (!completed) {
2565
+ opts.onError?.({ error: ERROR_CANCELLED });
2566
+ }
2440
2567
  }
2441
2568
  });
2442
- const handler = async (event) => {
2569
+ handler = async (event) => {
2443
2570
  if (event.origin !== expectedOrigin) return;
2444
2571
  const data = event.data;
2445
- if (!data || typeof data !== "object" || data.type !== "authorization_response") return;
2572
+ if (!data || typeof data !== "object" || data.type !== AUTHORIZATION_RESPONSE_MESSAGE_TYPE) return;
2446
2573
  const response = data.response;
2447
2574
  if (response.error) {
2575
+ completed = true;
2448
2576
  modal.close();
2449
2577
  opts.onError?.({ error: response.error, description: response.error_description });
2450
2578
  return;
2451
2579
  }
2452
2580
  if (!response.code) return;
2453
2581
  if (response.state !== state) {
2582
+ completed = true;
2454
2583
  modal.close();
2455
- opts.onError?.({ error: "state_mismatch" });
2584
+ opts.onError?.({ error: ERROR_STATE_MISMATCH });
2456
2585
  return;
2457
2586
  }
2458
2587
  try {
2459
- const res = await fetch(callbackUri, {
2460
- method: "POST",
2461
- credentials: "include",
2462
- headers: { "Content-Type": "application/json" },
2463
- body: JSON.stringify({ code: response.code, codeVerifier: pkce.verifier, state })
2464
- });
2465
- if (!res.ok) {
2466
- const body = await res.text().catch(() => "");
2467
- opts.onError?.({ error: "callback_failed", description: body });
2468
- modal.close();
2469
- return;
2470
- }
2471
- const payload = await res.json().catch(() => ({}));
2588
+ const result = await exchangeAuthorizationCode(callbackUri, pkce, state, response.code);
2589
+ completed = true;
2472
2590
  modal.close();
2473
- opts.onSuccess?.({
2474
- accessToken: payload.accessToken ?? payload.access_token,
2475
- expiresIn: payload.expiresIn ?? payload.expires_in,
2476
- scope: payload.scope
2477
- });
2591
+ opts.onSuccess?.(result);
2478
2592
  } catch (e) {
2479
- opts.onError?.({ error: "callback_exception", description: String(e) });
2593
+ const err2 = e;
2594
+ completed = true;
2595
+ opts.onError?.({
2596
+ error: err2.error ?? ERROR_CALLBACK_EXCEPTION,
2597
+ description: err2.description ?? String(e)
2598
+ });
2480
2599
  modal.close();
2481
2600
  }
2482
2601
  };
@@ -2487,19 +2606,10 @@ function startRedirectSignIn(opts, authorizeEndpoint, pkce, state) {
2487
2606
  const cookieValue = encodePkceState({ verifier: pkce.verifier, state, returnTo });
2488
2607
  const secure = window.location.protocol === "https:" ? "; Secure" : "";
2489
2608
  document.cookie = `${PKCE_COOKIE}=${cookieValue}; Path=${PKCE_COOKIE_PATH}; Max-Age=${PKCE_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secure}`;
2490
- const params = new URLSearchParams({
2491
- response_type: "code",
2492
- response_mode: "query",
2493
- client_id: opts.clientId,
2494
- redirect_uri: opts.redirectUri,
2495
- scope: opts.scope ?? DEFAULT_SCOPE,
2496
- state,
2497
- code_challenge: pkce.challenge,
2498
- code_challenge_method: pkce.method
2499
- });
2500
- if (opts.loginHint) params.set("login_hint", opts.loginHint);
2501
- if (opts.prompt) params.set("prompt", opts.prompt);
2502
- window.location.assign(`${authorizeEndpoint}?${params.toString()}`);
2609
+ window.location.assign(buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
2610
+ responseMode: RESPONSE_MODE_QUERY,
2611
+ prompt: opts.prompt
2612
+ }));
2503
2613
  }
2504
2614
 
2505
2615
  // src/elements.ts
@@ -2517,6 +2627,9 @@ function toCheckoutError(code, message, recoverable) {
2517
2627
  };
2518
2628
  }
2519
2629
  var DEFAULT_LINK_URL = "https://link.cimplify.io";
2630
+ var AUTH_CONTACT_TYPES = new Set(Object.values(ELEMENTS_AUTH_CONTACT_TYPES));
2631
+ var AUTH_MODES = new Set(Object.values(ELEMENTS_AUTH_MODES));
2632
+ var AUTH_PROMPTS = new Set(Object.values(ELEMENTS_AUTH_PROMPTS));
2520
2633
  function generateNonce() {
2521
2634
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
2522
2635
  return crypto.randomUUID().replace(/-/g, "").slice(0, 16);
@@ -2584,6 +2697,16 @@ function parseIframeMessage(data) {
2584
2697
  }
2585
2698
  switch (record.type) {
2586
2699
  case MESSAGE_TYPES.AUTH_REQUESTED:
2700
+ if (record.loginHint !== void 0 && typeof record.loginHint !== "string") return null;
2701
+ if (record.contactType !== void 0 && (typeof record.contactType !== "string" || !AUTH_CONTACT_TYPES.has(record.contactType))) {
2702
+ return null;
2703
+ }
2704
+ if (record.mode !== void 0 && (typeof record.mode !== "string" || !AUTH_MODES.has(record.mode))) {
2705
+ return null;
2706
+ }
2707
+ if (record.prompt !== void 0 && (typeof record.prompt !== "string" || !AUTH_PROMPTS.has(record.prompt))) {
2708
+ return null;
2709
+ }
2587
2710
  break;
2588
2711
  case MESSAGE_TYPES.ADDRESS_CHANGED:
2589
2712
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -2941,7 +3064,7 @@ var CimplifyElements = class {
2941
3064
  element.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
2942
3065
  });
2943
3066
  }
2944
- startEmbeddedAuth(sourceElement) {
3067
+ startEmbeddedAuth(sourceElement, request) {
2945
3068
  if (this.authInProgress) return;
2946
3069
  const auth = this.options.auth ?? {};
2947
3070
  const clientId = auth.clientId ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_CLIENT_ID");
@@ -2961,7 +3084,11 @@ var CimplifyElements = class {
2961
3084
  scope: auth.scope,
2962
3085
  issuer: auth.issuer,
2963
3086
  authUrl: auth.authUrl,
3087
+ loginHint: request.loginHint,
3088
+ prompt: request.prompt,
3089
+ uiMode: request.mode,
2964
3090
  mode: "modal",
3091
+ silentFirst: request.mode === ELEMENTS_AUTH_MODES.CHECKOUT && request.prompt !== ELEMENTS_AUTH_PROMPTS.LOGIN,
2965
3092
  onSuccess: async ({ accessToken }) => {
2966
3093
  this.authInProgress = false;
2967
3094
  if (!accessToken) {
@@ -3000,7 +3127,7 @@ var CimplifyElements = class {
3000
3127
  if (!sourceElement) return;
3001
3128
  switch (message.type) {
3002
3129
  case MESSAGE_TYPES.AUTH_REQUESTED:
3003
- this.startEmbeddedAuth(sourceElement);
3130
+ this.startEmbeddedAuth(sourceElement, message);
3004
3131
  break;
3005
3132
  case MESSAGE_TYPES.ADDRESS_CHANGED:
3006
3133
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -3296,4 +3423,4 @@ function createElements(client, businessId, options) {
3296
3423
  return new CimplifyElements(client, businessId, options);
3297
3424
  }
3298
3425
 
3299
- export { AUTHORIZATION_TYPE, AUTH_MUTATION, AuthService, BusinessService, CHECKOUT_MODE, CHECKOUT_MUTATION, CHECKOUT_STEP, CONTACT_TYPE, CartOperations, CatalogueQueries, CheckoutService, CimplifyElement, CimplifyElements, DEFAULT_COUNTRY, DEFAULT_CURRENCY, DEFAULT_ISSUER, DEVICE_TYPE, ELEMENT_TYPES, EVENT_TYPES, FxService, InventoryService, LINK_MUTATION, LINK_QUERY, LinkService, LiteService, MESSAGE_TYPES, MOBILE_MONEY_PROVIDER, ORDER_MUTATION, ORDER_TYPE, OrderQueries, PAYMENT_METHOD, PAYMENT_MUTATION, PAYMENT_STATE, PICKUP_TIME_TYPE, PKCE_COOKIE, PKCE_COOKIE_PATH, SchedulingService, combine, combineObject, createElements, decodePkceState, err, flatMap, fromPromise, generateIdempotencyKey, generatePkce, generateState, getAuthorizationEndpoint, getOrElse, isErr, isOk, mapError, mapResult, ok, safe, startSignIn, toNullable, tryCatch, unwrap };
3426
+ export { AUTHORIZATION_TYPE, AUTH_MUTATION, AuthService, BusinessService, CHECKOUT_MODE, CHECKOUT_MUTATION, CHECKOUT_STEP, CONTACT_TYPE, CartOperations, CatalogueQueries, CheckoutService, CimplifyElement, CimplifyElements, DEFAULT_COUNTRY, DEFAULT_CURRENCY, DEFAULT_ISSUER, DEVICE_TYPE, ELEMENTS_AUTH_CONTACT_TYPES, ELEMENTS_AUTH_MODES, ELEMENTS_AUTH_PROMPTS, ELEMENT_TYPES, EVENT_TYPES, FxService, InventoryService, LINK_MUTATION, LINK_QUERY, LinkService, LiteService, MESSAGE_TYPES, MOBILE_MONEY_PROVIDER, ORDER_MUTATION, ORDER_TYPE, OrderQueries, PAYMENT_METHOD, PAYMENT_MUTATION, PAYMENT_STATE, PICKUP_TIME_TYPE, PKCE_COOKIE, PKCE_COOKIE_PATH, SchedulingService, combine, combineObject, createElements, decodePkceState, err, flatMap, fromPromise, generateIdempotencyKey, generatePkce, generateState, getAuthorizationEndpoint, getOrElse, isErr, isOk, mapError, mapResult, ok, safe, startSignIn, toNullable, tryCatch, unwrap };
@@ -1,5 +1,5 @@
1
1
  import { createMockApp } from './chunk-FVGVJ4TC.mjs';
2
- import { createCimplifyClient } from './chunk-JAPCAZN4.mjs';
2
+ import { createCimplifyClient } from './chunk-KNPE4WCQ.mjs';
3
3
  import { z } from 'zod';
4
4
 
5
5
  var cimplifyRegistry = z.registry();
@@ -2272,6 +2272,17 @@ var MESSAGE_TYPES = {
2272
2272
  ORDER_TYPE_CHANGED: "order_type_changed",
2273
2273
  REQUEST_SUBMIT: "request_submit"
2274
2274
  };
2275
+ var ELEMENTS_AUTH_CONTACT_TYPES = {
2276
+ EMAIL: "email",
2277
+ PHONE: "phone"
2278
+ };
2279
+ var ELEMENTS_AUTH_PROMPTS = {
2280
+ LOGIN: "login"
2281
+ };
2282
+ var ELEMENTS_AUTH_MODES = {
2283
+ CHECKOUT: "checkout",
2284
+ DEFAULT: "default"
2285
+ };
2275
2286
  var EVENT_TYPES = {
2276
2287
  READY: "ready",
2277
2288
  AUTHENTICATED: "authenticated",
@@ -2406,6 +2417,119 @@ function openModalIframe(opts) {
2406
2417
 
2407
2418
  // src/sign-in.ts
2408
2419
  var DEFAULT_SCOPE = "openid email phone profile";
2420
+ var DEFAULT_SILENT_TIMEOUT_MS = 900;
2421
+ var RESPONSE_TYPE_CODE = "code";
2422
+ var RESPONSE_MODE_WEB_MESSAGE = "web_message";
2423
+ var RESPONSE_MODE_QUERY = "query";
2424
+ var PROMPT_NONE = "none";
2425
+ var AUTHORIZATION_RESPONSE_MESSAGE_TYPE = "authorization_response";
2426
+ var ERROR_STATE_MISMATCH = "state_mismatch";
2427
+ var ERROR_CALLBACK_FAILED = "callback_failed";
2428
+ var ERROR_CALLBACK_EXCEPTION = "callback_exception";
2429
+ var ERROR_CANCELLED = "cancelled";
2430
+ var ERROR_LOGIN_REQUIRED = "login_required";
2431
+ var ERROR_CONSENT_REQUIRED = "consent_required";
2432
+ var ERROR_INTERACTION_REQUIRED = "interaction_required";
2433
+ var INTERACTIVE_AUTH_ERRORS = /* @__PURE__ */ new Set([
2434
+ ERROR_LOGIN_REQUIRED,
2435
+ ERROR_CONSENT_REQUIRED,
2436
+ ERROR_INTERACTION_REQUIRED
2437
+ ]);
2438
+ function buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, urlOpts) {
2439
+ const params = new URLSearchParams({
2440
+ response_type: RESPONSE_TYPE_CODE,
2441
+ response_mode: urlOpts.responseMode,
2442
+ client_id: opts.clientId,
2443
+ redirect_uri: opts.redirectUri,
2444
+ scope: opts.scope ?? DEFAULT_SCOPE,
2445
+ state,
2446
+ code_challenge: pkce.challenge,
2447
+ code_challenge_method: pkce.method
2448
+ });
2449
+ if (opts.loginHint) params.set("login_hint", opts.loginHint);
2450
+ if (urlOpts.prompt) params.set("prompt", urlOpts.prompt);
2451
+ if (opts.uiMode) params.set("ui_mode", opts.uiMode);
2452
+ return `${authorizeEndpoint}?${params.toString()}`;
2453
+ }
2454
+ async function exchangeAuthorizationCode(callbackUri, pkce, state, code) {
2455
+ const res = await fetch(callbackUri, {
2456
+ method: "POST",
2457
+ credentials: "include",
2458
+ headers: { "Content-Type": "application/json" },
2459
+ body: JSON.stringify({ code, codeVerifier: pkce.verifier, state })
2460
+ });
2461
+ if (!res.ok) {
2462
+ const body = await res.text().catch(() => "");
2463
+ throw { error: ERROR_CALLBACK_FAILED, description: body };
2464
+ }
2465
+ const payload = await res.json().catch(() => ({}));
2466
+ return {
2467
+ accessToken: payload.accessToken ?? payload.access_token,
2468
+ expiresIn: payload.expiresIn ?? payload.expires_in,
2469
+ scope: payload.scope
2470
+ };
2471
+ }
2472
+ async function trySilentModalSignIn(opts, authorizeEndpoint, callbackUri, pkce, state) {
2473
+ const expectedOrigin = new URL(authorizeEndpoint).origin;
2474
+ const iframe = document.createElement("iframe");
2475
+ iframe.style.display = "none";
2476
+ iframe.setAttribute("aria-hidden", "true");
2477
+ iframe.setAttribute("sandbox", "allow-scripts allow-same-origin");
2478
+ iframe.src = buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
2479
+ responseMode: RESPONSE_MODE_WEB_MESSAGE,
2480
+ prompt: PROMPT_NONE
2481
+ });
2482
+ return new Promise((resolve) => {
2483
+ let settled = false;
2484
+ let handler = () => {
2485
+ };
2486
+ const timeout = setTimeout(() => finish(false), opts.silentTimeoutMs ?? DEFAULT_SILENT_TIMEOUT_MS);
2487
+ const cleanup = () => {
2488
+ window.removeEventListener("message", handler);
2489
+ iframe.remove();
2490
+ clearTimeout(timeout);
2491
+ };
2492
+ const finish = (handled) => {
2493
+ if (settled) return;
2494
+ settled = true;
2495
+ cleanup();
2496
+ resolve(handled);
2497
+ };
2498
+ handler = async (event) => {
2499
+ if (event.origin !== expectedOrigin) return;
2500
+ const data = event.data;
2501
+ if (!data || typeof data !== "object" || data.type !== AUTHORIZATION_RESPONSE_MESSAGE_TYPE) return;
2502
+ const response = data.response;
2503
+ if (response.error) {
2504
+ if (INTERACTIVE_AUTH_ERRORS.has(response.error)) {
2505
+ finish(false);
2506
+ return;
2507
+ }
2508
+ opts.onError?.({ error: response.error, description: response.error_description });
2509
+ finish(true);
2510
+ return;
2511
+ }
2512
+ if (!response.code) return;
2513
+ if (response.state !== state) {
2514
+ opts.onError?.({ error: ERROR_STATE_MISMATCH });
2515
+ finish(true);
2516
+ return;
2517
+ }
2518
+ try {
2519
+ opts.onSuccess?.(await exchangeAuthorizationCode(callbackUri, pkce, state, response.code));
2520
+ } catch (e) {
2521
+ const err2 = e;
2522
+ opts.onError?.({
2523
+ error: err2.error ?? ERROR_CALLBACK_EXCEPTION,
2524
+ description: err2.description ?? String(e)
2525
+ });
2526
+ }
2527
+ finish(true);
2528
+ };
2529
+ window.addEventListener("message", handler);
2530
+ document.body.appendChild(iframe);
2531
+ });
2532
+ }
2409
2533
  function resolveAuthorizeEndpoint(opts) {
2410
2534
  if (opts.authUrl) {
2411
2535
  return Promise.resolve(`${opts.authUrl.replace(/\/$/, "")}/oauth/authorize`);
@@ -2421,64 +2545,59 @@ async function startSignIn(opts) {
2421
2545
  startRedirectSignIn(opts, authorizeEndpoint, pkce, state);
2422
2546
  return;
2423
2547
  }
2424
- const params = new URLSearchParams({
2425
- response_type: "code",
2426
- response_mode: "web_message",
2427
- client_id: opts.clientId,
2428
- redirect_uri: opts.redirectUri,
2429
- scope: opts.scope ?? DEFAULT_SCOPE,
2430
- state,
2431
- code_challenge: pkce.challenge,
2432
- code_challenge_method: pkce.method
2548
+ if (opts.silentFirst && !opts.prompt) {
2549
+ const handledSilently = await trySilentModalSignIn(opts, authorizeEndpoint, callbackUri, pkce, state);
2550
+ if (handledSilently) {
2551
+ return;
2552
+ }
2553
+ }
2554
+ const src = buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
2555
+ responseMode: RESPONSE_MODE_WEB_MESSAGE,
2556
+ prompt: opts.prompt
2433
2557
  });
2434
- if (opts.loginHint) params.set("login_hint", opts.loginHint);
2435
- if (opts.prompt) params.set("prompt", opts.prompt);
2436
- const src = `${authorizeEndpoint}?${params.toString()}`;
2437
2558
  const expectedOrigin = new URL(authorizeEndpoint).origin;
2559
+ let completed = false;
2560
+ let handler = () => {
2561
+ };
2438
2562
  const modal = openModalIframe({
2439
2563
  src,
2440
2564
  onClose: () => {
2441
2565
  window.removeEventListener("message", handler);
2566
+ if (!completed) {
2567
+ opts.onError?.({ error: ERROR_CANCELLED });
2568
+ }
2442
2569
  }
2443
2570
  });
2444
- const handler = async (event) => {
2571
+ handler = async (event) => {
2445
2572
  if (event.origin !== expectedOrigin) return;
2446
2573
  const data = event.data;
2447
- if (!data || typeof data !== "object" || data.type !== "authorization_response") return;
2574
+ if (!data || typeof data !== "object" || data.type !== AUTHORIZATION_RESPONSE_MESSAGE_TYPE) return;
2448
2575
  const response = data.response;
2449
2576
  if (response.error) {
2577
+ completed = true;
2450
2578
  modal.close();
2451
2579
  opts.onError?.({ error: response.error, description: response.error_description });
2452
2580
  return;
2453
2581
  }
2454
2582
  if (!response.code) return;
2455
2583
  if (response.state !== state) {
2584
+ completed = true;
2456
2585
  modal.close();
2457
- opts.onError?.({ error: "state_mismatch" });
2586
+ opts.onError?.({ error: ERROR_STATE_MISMATCH });
2458
2587
  return;
2459
2588
  }
2460
2589
  try {
2461
- const res = await fetch(callbackUri, {
2462
- method: "POST",
2463
- credentials: "include",
2464
- headers: { "Content-Type": "application/json" },
2465
- body: JSON.stringify({ code: response.code, codeVerifier: pkce.verifier, state })
2466
- });
2467
- if (!res.ok) {
2468
- const body = await res.text().catch(() => "");
2469
- opts.onError?.({ error: "callback_failed", description: body });
2470
- modal.close();
2471
- return;
2472
- }
2473
- const payload = await res.json().catch(() => ({}));
2590
+ const result = await exchangeAuthorizationCode(callbackUri, pkce, state, response.code);
2591
+ completed = true;
2474
2592
  modal.close();
2475
- opts.onSuccess?.({
2476
- accessToken: payload.accessToken ?? payload.access_token,
2477
- expiresIn: payload.expiresIn ?? payload.expires_in,
2478
- scope: payload.scope
2479
- });
2593
+ opts.onSuccess?.(result);
2480
2594
  } catch (e) {
2481
- opts.onError?.({ error: "callback_exception", description: String(e) });
2595
+ const err2 = e;
2596
+ completed = true;
2597
+ opts.onError?.({
2598
+ error: err2.error ?? ERROR_CALLBACK_EXCEPTION,
2599
+ description: err2.description ?? String(e)
2600
+ });
2482
2601
  modal.close();
2483
2602
  }
2484
2603
  };
@@ -2489,19 +2608,10 @@ function startRedirectSignIn(opts, authorizeEndpoint, pkce, state) {
2489
2608
  const cookieValue = encodePkceState({ verifier: pkce.verifier, state, returnTo });
2490
2609
  const secure = window.location.protocol === "https:" ? "; Secure" : "";
2491
2610
  document.cookie = `${PKCE_COOKIE}=${cookieValue}; Path=${PKCE_COOKIE_PATH}; Max-Age=${PKCE_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secure}`;
2492
- const params = new URLSearchParams({
2493
- response_type: "code",
2494
- response_mode: "query",
2495
- client_id: opts.clientId,
2496
- redirect_uri: opts.redirectUri,
2497
- scope: opts.scope ?? DEFAULT_SCOPE,
2498
- state,
2499
- code_challenge: pkce.challenge,
2500
- code_challenge_method: pkce.method
2501
- });
2502
- if (opts.loginHint) params.set("login_hint", opts.loginHint);
2503
- if (opts.prompt) params.set("prompt", opts.prompt);
2504
- window.location.assign(`${authorizeEndpoint}?${params.toString()}`);
2611
+ window.location.assign(buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
2612
+ responseMode: RESPONSE_MODE_QUERY,
2613
+ prompt: opts.prompt
2614
+ }));
2505
2615
  }
2506
2616
 
2507
2617
  // src/elements.ts
@@ -2519,6 +2629,9 @@ function toCheckoutError(code, message, recoverable) {
2519
2629
  };
2520
2630
  }
2521
2631
  var DEFAULT_LINK_URL = "https://link.cimplify.io";
2632
+ var AUTH_CONTACT_TYPES = new Set(Object.values(ELEMENTS_AUTH_CONTACT_TYPES));
2633
+ var AUTH_MODES = new Set(Object.values(ELEMENTS_AUTH_MODES));
2634
+ var AUTH_PROMPTS = new Set(Object.values(ELEMENTS_AUTH_PROMPTS));
2522
2635
  function generateNonce() {
2523
2636
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
2524
2637
  return crypto.randomUUID().replace(/-/g, "").slice(0, 16);
@@ -2586,6 +2699,16 @@ function parseIframeMessage(data) {
2586
2699
  }
2587
2700
  switch (record.type) {
2588
2701
  case MESSAGE_TYPES.AUTH_REQUESTED:
2702
+ if (record.loginHint !== void 0 && typeof record.loginHint !== "string") return null;
2703
+ if (record.contactType !== void 0 && (typeof record.contactType !== "string" || !AUTH_CONTACT_TYPES.has(record.contactType))) {
2704
+ return null;
2705
+ }
2706
+ if (record.mode !== void 0 && (typeof record.mode !== "string" || !AUTH_MODES.has(record.mode))) {
2707
+ return null;
2708
+ }
2709
+ if (record.prompt !== void 0 && (typeof record.prompt !== "string" || !AUTH_PROMPTS.has(record.prompt))) {
2710
+ return null;
2711
+ }
2589
2712
  break;
2590
2713
  case MESSAGE_TYPES.ADDRESS_CHANGED:
2591
2714
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -2943,7 +3066,7 @@ var CimplifyElements = class {
2943
3066
  element.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
2944
3067
  });
2945
3068
  }
2946
- startEmbeddedAuth(sourceElement) {
3069
+ startEmbeddedAuth(sourceElement, request) {
2947
3070
  if (this.authInProgress) return;
2948
3071
  const auth = this.options.auth ?? {};
2949
3072
  const clientId = auth.clientId ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_CLIENT_ID");
@@ -2963,7 +3086,11 @@ var CimplifyElements = class {
2963
3086
  scope: auth.scope,
2964
3087
  issuer: auth.issuer,
2965
3088
  authUrl: auth.authUrl,
3089
+ loginHint: request.loginHint,
3090
+ prompt: request.prompt,
3091
+ uiMode: request.mode,
2966
3092
  mode: "modal",
3093
+ silentFirst: request.mode === ELEMENTS_AUTH_MODES.CHECKOUT && request.prompt !== ELEMENTS_AUTH_PROMPTS.LOGIN,
2967
3094
  onSuccess: async ({ accessToken }) => {
2968
3095
  this.authInProgress = false;
2969
3096
  if (!accessToken) {
@@ -3002,7 +3129,7 @@ var CimplifyElements = class {
3002
3129
  if (!sourceElement) return;
3003
3130
  switch (message.type) {
3004
3131
  case MESSAGE_TYPES.AUTH_REQUESTED:
3005
- this.startEmbeddedAuth(sourceElement);
3132
+ this.startEmbeddedAuth(sourceElement, message);
3006
3133
  break;
3007
3134
  case MESSAGE_TYPES.ADDRESS_CHANGED:
3008
3135
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -3315,6 +3442,9 @@ exports.DEFAULT_COUNTRY = DEFAULT_COUNTRY;
3315
3442
  exports.DEFAULT_CURRENCY = DEFAULT_CURRENCY;
3316
3443
  exports.DEFAULT_ISSUER = DEFAULT_ISSUER;
3317
3444
  exports.DEVICE_TYPE = DEVICE_TYPE;
3445
+ exports.ELEMENTS_AUTH_CONTACT_TYPES = ELEMENTS_AUTH_CONTACT_TYPES;
3446
+ exports.ELEMENTS_AUTH_MODES = ELEMENTS_AUTH_MODES;
3447
+ exports.ELEMENTS_AUTH_PROMPTS = ELEMENTS_AUTH_PROMPTS;
3318
3448
  exports.ELEMENT_TYPES = ELEMENT_TYPES;
3319
3449
  exports.EVENT_TYPES = EVENT_TYPES;
3320
3450
  exports.FxService = FxService;
@@ -1,4 +1,4 @@
1
- import { ac as CimplifyClient } from './client-ByI_3jfL.mjs';
1
+ import { ac as CimplifyClient } from './client-Dyo3dvNy.mjs';
2
2
  import { A as AppHandle, C as CreateAppOptions } from './server-D8rwqZQ6.mjs';
3
3
 
4
4
  /**