@cimplify/sdk 0.66.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 (55) 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-J3MGY6AU.js → chunk-5HAUJBOK.js} +36 -82
  6. package/dist/chunk-E6T5VJMG.mjs +156 -0
  7. package/dist/{chunk-3G4QCENX.mjs → chunk-FVGVJ4TC.mjs} +12 -50
  8. package/dist/chunk-IQLJJW2H.js +168 -0
  9. package/dist/{chunk-227XTAEB.mjs → chunk-KNPE4WCQ.mjs} +2 -48
  10. package/dist/{chunk-H6DBPHMZ.js → chunk-NGQCWFKF.js} +4 -4
  11. package/dist/{chunk-R6363CC7.mjs → chunk-SOV4H6PQ.mjs} +509 -79
  12. package/dist/{chunk-HCZTBWU4.js → chunk-SXGFJEME.js} +12 -50
  13. package/dist/{chunk-MWI5GAUF.mjs → chunk-TAKORJP4.mjs} +2 -2
  14. package/dist/{chunk-AVQL3TSJ.js → chunk-WCSAZRNC.js} +519 -78
  15. package/dist/{client-CUrA1uQ0.d.mts → client-CBE7ksYC.d.mts} +1 -1
  16. package/dist/{client-Bo5rujc2.d.ts → client-CfeQRwhl.d.ts} +55 -21
  17. package/dist/{client-DasPHOJh.d.ts → client-DlXfZy7N.d.ts} +1 -1
  18. package/dist/{client-Dka2cGhu.d.mts → client-Dyo3dvNy.d.mts} +55 -21
  19. package/dist/index.d.mts +2 -2
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +104 -88
  22. package/dist/index.mjs +16 -12
  23. package/dist/mock/cli.mjs +12 -50
  24. package/dist/mock/library.js +12 -50
  25. package/dist/mock/library.mjs +12 -50
  26. package/dist/mock/msw.js +12 -50
  27. package/dist/mock/msw.mjs +12 -50
  28. package/dist/react.d.mts +44 -44
  29. package/dist/react.d.ts +44 -44
  30. package/dist/react.js +298 -175
  31. package/dist/react.mjs +240 -117
  32. package/dist/server.d.mts +2 -2
  33. package/dist/server.d.ts +2 -2
  34. package/dist/server.js +16 -9
  35. package/dist/server.mjs +11 -4
  36. package/dist/{sign-in-dr7m09nm.d.ts → sign-in-DQlIdqsi.d.mts} +14 -1
  37. package/dist/{sign-in-dr7m09nm.d.mts → sign-in-DQlIdqsi.d.ts} +14 -1
  38. package/dist/styles.css +1 -1
  39. package/dist/testing/msw.js +2 -2
  40. package/dist/testing/msw.mjs +1 -1
  41. package/dist/testing/suite.d.mts +2 -2
  42. package/dist/testing/suite.d.ts +2 -2
  43. package/dist/testing/suite.js +23 -23
  44. package/dist/testing/suite.mjs +4 -4
  45. package/dist/testing.d.mts +17 -17
  46. package/dist/testing.d.ts +17 -17
  47. package/dist/testing.js +79 -79
  48. package/dist/testing.mjs +5 -5
  49. package/package.json +1 -1
  50. package/registry/index.json +0 -9
  51. package/dist/chunk-3Z3FQH7X.mjs +0 -323
  52. package/dist/chunk-7BKKBJQM.mjs +0 -52
  53. package/dist/chunk-GDAGM26J.js +0 -338
  54. package/dist/chunk-KWYI2TTA.js +0 -60
  55. package/registry/account.json +0 -15
@@ -1758,8 +1758,20 @@ var LinkService = class {
1758
1758
  }
1759
1759
  async verifyOtp(input, opts) {
1760
1760
  const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
1761
+ const { business_id: _ignoredBusinessId, ...body } = input;
1761
1762
  const result = await safe(
1762
- this.client.linkPost("/v1/link/auth/verify-otp", input, { idempotencyKey })
1763
+ this.client.linkPost("/v1/link/auth/verify-otp", body, { idempotencyKey })
1764
+ );
1765
+ if (result.ok && result.value.session_token) {
1766
+ this.client.setAccessToken(result.value.session_token);
1767
+ }
1768
+ return result;
1769
+ }
1770
+ async refreshSession(sessionToken, opts) {
1771
+ const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
1772
+ const body = sessionToken ? { session_token: sessionToken } : {};
1773
+ const result = await safe(
1774
+ this.client.linkPost("/v1/link/auth/refresh", body, { idempotencyKey })
1763
1775
  );
1764
1776
  if (result.ok && result.value.session_token) {
1765
1777
  this.client.setAccessToken(result.value.session_token);
@@ -2241,30 +2253,39 @@ var MESSAGE_TYPES = {
2241
2253
  SET_TOKEN: "set_token",
2242
2254
  SET_CART: "set_cart",
2243
2255
  GET_DATA: "get_data",
2256
+ NAVIGATE: "navigate",
2244
2257
  REFRESH_TOKEN: "refresh_token",
2245
2258
  LOGOUT: "logout",
2246
2259
  PROCESS_CHECKOUT: "process_checkout",
2247
2260
  ABORT_CHECKOUT: "abort_checkout",
2248
2261
  READY: "ready",
2249
2262
  HEIGHT_CHANGE: "height_change",
2250
- AUTHENTICATED: "authenticated",
2251
- REQUIRES_OTP: "requires_otp",
2252
2263
  ERROR: "error",
2253
2264
  ADDRESS_CHANGED: "address_changed",
2254
2265
  ADDRESS_SELECTED: "address_selected",
2255
2266
  PAYMENT_METHOD_SELECTED: "payment_method_selected",
2256
- TOKEN_REFRESHED: "token_refreshed",
2257
2267
  LOGOUT_COMPLETE: "logout_complete",
2268
+ AUTH_REQUESTED: "auth_requested",
2258
2269
  CONTACT_PROVIDED: "contact_provided",
2259
2270
  CHECKOUT_STATUS: "checkout_status",
2260
2271
  CHECKOUT_COMPLETE: "checkout_complete",
2261
2272
  ORDER_TYPE_CHANGED: "order_type_changed",
2262
2273
  REQUEST_SUBMIT: "request_submit"
2263
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
+ };
2264
2286
  var EVENT_TYPES = {
2265
2287
  READY: "ready",
2266
2288
  AUTHENTICATED: "authenticated",
2267
- REQUIRES_OTP: "requires_otp",
2268
2289
  ERROR: "error",
2269
2290
  CHANGE: "change",
2270
2291
  BLUR: "blur",
@@ -2273,6 +2294,326 @@ var EVENT_TYPES = {
2273
2294
  REQUEST_SUBMIT: "request_submit"
2274
2295
  };
2275
2296
 
2297
+ // src/internal/pkce.ts
2298
+ var VERIFIER_BYTES = 64;
2299
+ async function generatePkce() {
2300
+ const random = new Uint8Array(VERIFIER_BYTES);
2301
+ crypto.getRandomValues(random);
2302
+ const verifier = base64UrlEncode(random);
2303
+ const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
2304
+ const challenge = base64UrlEncode(new Uint8Array(digest));
2305
+ return { verifier, challenge, method: "S256" };
2306
+ }
2307
+ function generateState(byteLength = 16) {
2308
+ const buf = new Uint8Array(byteLength);
2309
+ crypto.getRandomValues(buf);
2310
+ return base64UrlEncode(buf);
2311
+ }
2312
+ function base64UrlEncode(bytes) {
2313
+ let str = "";
2314
+ for (const byte of bytes) str += String.fromCharCode(byte);
2315
+ return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
2316
+ }
2317
+
2318
+ // src/internal/pkce-cookie.ts
2319
+ var PKCE_COOKIE = "cimplify_pkce";
2320
+ var PKCE_COOKIE_PATH = "/auth";
2321
+ var PKCE_COOKIE_MAX_AGE_SECONDS = 600;
2322
+ function encodePkceState(state) {
2323
+ return encodeURIComponent(JSON.stringify(state));
2324
+ }
2325
+ function decodePkceState(raw) {
2326
+ try {
2327
+ const parsed = JSON.parse(decodeURIComponent(raw));
2328
+ if (typeof parsed?.verifier === "string" && typeof parsed.state === "string" && typeof parsed.returnTo === "string") {
2329
+ return { verifier: parsed.verifier, state: parsed.state, returnTo: parsed.returnTo };
2330
+ }
2331
+ } catch {
2332
+ }
2333
+ return null;
2334
+ }
2335
+
2336
+ // src/internal/discovery.ts
2337
+ var DEFAULT_ISSUER = "https://api.cimplify.io";
2338
+ var DEFAULT_AUTHORIZATION_ENDPOINT = "https://auth.cimplify.io/oauth/authorize";
2339
+ function fallbackAuthorizationEndpoint(issuerBase) {
2340
+ if (issuerBase === DEFAULT_ISSUER) return DEFAULT_AUTHORIZATION_ENDPOINT;
2341
+ throw new Error(
2342
+ `OIDC discovery for "${issuerBase}" is unreachable and no fallback authorize endpoint is known for it. Make discovery reachable (enable CORS) or pass authUrl.`
2343
+ );
2344
+ }
2345
+ var cache = /* @__PURE__ */ new Map();
2346
+ function fetchDiscovery(issuer) {
2347
+ const base = issuer.replace(/\/$/, "");
2348
+ let pending = cache.get(base);
2349
+ if (!pending) {
2350
+ pending = fetch(`${base}/.well-known/openid-configuration`).then((res) => {
2351
+ if (!res.ok) throw new Error(`oidc discovery failed: ${res.status}`);
2352
+ return res.json();
2353
+ });
2354
+ pending.catch(() => cache.delete(base));
2355
+ cache.set(base, pending);
2356
+ }
2357
+ return pending;
2358
+ }
2359
+ async function getAuthorizationEndpoint(issuer) {
2360
+ const base = issuer.replace(/\/$/, "");
2361
+ try {
2362
+ const doc = await fetchDiscovery(base);
2363
+ if (doc.authorization_endpoint) return doc.authorization_endpoint;
2364
+ } catch {
2365
+ }
2366
+ return fallbackAuthorizationEndpoint(base);
2367
+ }
2368
+
2369
+ // src/internal/modal-iframe.ts
2370
+ function openModalIframe(opts) {
2371
+ const overlay = document.createElement("div");
2372
+ overlay.dataset.cimplifyModal = "1";
2373
+ Object.assign(overlay.style, {
2374
+ position: "fixed",
2375
+ inset: "0",
2376
+ background: "rgba(15, 18, 24, 0.55)",
2377
+ zIndex: "2147483647",
2378
+ display: "grid",
2379
+ placeItems: "center",
2380
+ backdropFilter: "blur(2px)"
2381
+ });
2382
+ const card = document.createElement("div");
2383
+ Object.assign(card.style, {
2384
+ width: `${opts.width ?? 480}px`,
2385
+ maxWidth: "calc(100vw - 24px)",
2386
+ height: `${opts.height ?? 720}px`,
2387
+ maxHeight: "calc(100vh - 32px)"
2388
+ });
2389
+ const iframe = document.createElement("iframe");
2390
+ iframe.src = opts.src;
2391
+ iframe.style.width = "100%";
2392
+ iframe.style.height = "100%";
2393
+ iframe.style.border = "none";
2394
+ iframe.style.background = "transparent";
2395
+ iframe.setAttribute(
2396
+ "sandbox",
2397
+ opts.sandbox ?? "allow-scripts allow-same-origin allow-forms allow-popups"
2398
+ );
2399
+ iframe.setAttribute("allow", "publickey-credentials-get; publickey-credentials-create");
2400
+ card.appendChild(iframe);
2401
+ overlay.appendChild(card);
2402
+ document.body.appendChild(overlay);
2403
+ const close = () => {
2404
+ overlay.remove();
2405
+ document.removeEventListener("keydown", onKey);
2406
+ opts.onClose?.();
2407
+ };
2408
+ const onKey = (e) => {
2409
+ if (e.key === "Escape") close();
2410
+ };
2411
+ overlay.addEventListener("click", (e) => {
2412
+ if (e.target === overlay) close();
2413
+ });
2414
+ document.addEventListener("keydown", onKey);
2415
+ return { iframe, close };
2416
+ }
2417
+
2418
+ // src/sign-in.ts
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
+ }
2533
+ function resolveAuthorizeEndpoint(opts) {
2534
+ if (opts.authUrl) {
2535
+ return Promise.resolve(`${opts.authUrl.replace(/\/$/, "")}/oauth/authorize`);
2536
+ }
2537
+ return getAuthorizationEndpoint(opts.issuer ?? DEFAULT_ISSUER);
2538
+ }
2539
+ async function startSignIn(opts) {
2540
+ const callbackUri = opts.callbackUri ?? "/auth/callback";
2541
+ const pkce = await generatePkce();
2542
+ const state = generateState();
2543
+ const authorizeEndpoint = await resolveAuthorizeEndpoint(opts);
2544
+ if ((opts.mode ?? "redirect") === "redirect") {
2545
+ startRedirectSignIn(opts, authorizeEndpoint, pkce, state);
2546
+ return;
2547
+ }
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
2557
+ });
2558
+ const expectedOrigin = new URL(authorizeEndpoint).origin;
2559
+ let completed = false;
2560
+ let handler = () => {
2561
+ };
2562
+ const modal = openModalIframe({
2563
+ src,
2564
+ onClose: () => {
2565
+ window.removeEventListener("message", handler);
2566
+ if (!completed) {
2567
+ opts.onError?.({ error: ERROR_CANCELLED });
2568
+ }
2569
+ }
2570
+ });
2571
+ handler = async (event) => {
2572
+ if (event.origin !== expectedOrigin) return;
2573
+ const data = event.data;
2574
+ if (!data || typeof data !== "object" || data.type !== AUTHORIZATION_RESPONSE_MESSAGE_TYPE) return;
2575
+ const response = data.response;
2576
+ if (response.error) {
2577
+ completed = true;
2578
+ modal.close();
2579
+ opts.onError?.({ error: response.error, description: response.error_description });
2580
+ return;
2581
+ }
2582
+ if (!response.code) return;
2583
+ if (response.state !== state) {
2584
+ completed = true;
2585
+ modal.close();
2586
+ opts.onError?.({ error: ERROR_STATE_MISMATCH });
2587
+ return;
2588
+ }
2589
+ try {
2590
+ const result = await exchangeAuthorizationCode(callbackUri, pkce, state, response.code);
2591
+ completed = true;
2592
+ modal.close();
2593
+ opts.onSuccess?.(result);
2594
+ } catch (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
+ });
2601
+ modal.close();
2602
+ }
2603
+ };
2604
+ window.addEventListener("message", handler);
2605
+ }
2606
+ function startRedirectSignIn(opts, authorizeEndpoint, pkce, state) {
2607
+ const returnTo = opts.returnTo ?? window.location.pathname + window.location.search;
2608
+ const cookieValue = encodePkceState({ verifier: pkce.verifier, state, returnTo });
2609
+ const secure = window.location.protocol === "https:" ? "; Secure" : "";
2610
+ document.cookie = `${PKCE_COOKIE}=${cookieValue}; Path=${PKCE_COOKIE_PATH}; Max-Age=${PKCE_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secure}`;
2611
+ window.location.assign(buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
2612
+ responseMode: RESPONSE_MODE_QUERY,
2613
+ prompt: opts.prompt
2614
+ }));
2615
+ }
2616
+
2276
2617
  // src/elements.ts
2277
2618
  function toCheckoutError(code, message, recoverable) {
2278
2619
  const hint = chunkXA3ZNR75_js.getErrorHint(code);
@@ -2288,12 +2629,36 @@ function toCheckoutError(code, message, recoverable) {
2288
2629
  };
2289
2630
  }
2290
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));
2291
2635
  function generateNonce() {
2292
2636
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
2293
2637
  return crypto.randomUUID().replace(/-/g, "").slice(0, 16);
2294
2638
  }
2295
2639
  return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
2296
2640
  }
2641
+ function readPublicEnv(name) {
2642
+ try {
2643
+ const processLike = globalThis.process;
2644
+ const value = processLike?.env?.[name];
2645
+ return value && value.trim() ? value : void 0;
2646
+ } catch {
2647
+ return void 0;
2648
+ }
2649
+ }
2650
+ function decodeJwtSub(token) {
2651
+ const [, payload] = token.split(".");
2652
+ if (!payload || typeof atob === "undefined") return "";
2653
+ try {
2654
+ const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
2655
+ const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
2656
+ const parsed = JSON.parse(atob(padded));
2657
+ return typeof parsed.sub === "string" ? parsed.sub : "";
2658
+ } catch {
2659
+ return "";
2660
+ }
2661
+ }
2297
2662
  function isAllowedOrigin(origin) {
2298
2663
  try {
2299
2664
  const url = new URL(origin);
@@ -2309,7 +2674,21 @@ function isAllowedOrigin(origin) {
2309
2674
  return false;
2310
2675
  }
2311
2676
  }
2312
- var KNOWN_IFRAME_TYPES = new Set(Object.values(MESSAGE_TYPES));
2677
+ var KNOWN_IFRAME_TYPES = /* @__PURE__ */ new Set([
2678
+ MESSAGE_TYPES.READY,
2679
+ MESSAGE_TYPES.HEIGHT_CHANGE,
2680
+ MESSAGE_TYPES.AUTH_REQUESTED,
2681
+ MESSAGE_TYPES.ERROR,
2682
+ MESSAGE_TYPES.ADDRESS_CHANGED,
2683
+ MESSAGE_TYPES.ADDRESS_SELECTED,
2684
+ MESSAGE_TYPES.PAYMENT_METHOD_SELECTED,
2685
+ MESSAGE_TYPES.CONTACT_PROVIDED,
2686
+ MESSAGE_TYPES.LOGOUT_COMPLETE,
2687
+ MESSAGE_TYPES.CHECKOUT_STATUS,
2688
+ MESSAGE_TYPES.CHECKOUT_COMPLETE,
2689
+ MESSAGE_TYPES.ORDER_TYPE_CHANGED,
2690
+ MESSAGE_TYPES.REQUEST_SUBMIT
2691
+ ]);
2313
2692
  function parseIframeMessage(data) {
2314
2693
  if (!data || typeof data !== "object") {
2315
2694
  return null;
@@ -2319,11 +2698,17 @@ function parseIframeMessage(data) {
2319
2698
  return null;
2320
2699
  }
2321
2700
  switch (record.type) {
2322
- case MESSAGE_TYPES.AUTHENTICATED:
2323
- if (typeof record.token !== "string") return null;
2324
- break;
2325
- case MESSAGE_TYPES.TOKEN_REFRESHED:
2326
- if (typeof record.token !== "string") return null;
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
+ }
2327
2712
  break;
2328
2713
  case MESSAGE_TYPES.ADDRESS_CHANGED:
2329
2714
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -2341,13 +2726,13 @@ function parseIframeMessage(data) {
2341
2726
  case MESSAGE_TYPES.CHECKOUT_COMPLETE:
2342
2727
  if (typeof record.success !== "boolean") return null;
2343
2728
  break;
2729
+ case MESSAGE_TYPES.CHECKOUT_STATUS:
2730
+ if (typeof record.status !== "string" || !record.context || typeof record.context !== "object") return null;
2731
+ break;
2344
2732
  case MESSAGE_TYPES.READY:
2345
2733
  case MESSAGE_TYPES.HEIGHT_CHANGE:
2346
2734
  if (typeof record.height !== "number") return null;
2347
2735
  break;
2348
- case MESSAGE_TYPES.REQUIRES_OTP:
2349
- if (typeof record.contactMasked !== "string") return null;
2350
- break;
2351
2736
  case MESSAGE_TYPES.ORDER_TYPE_CHANGED:
2352
2737
  if (typeof record.orderType !== "string") return null;
2353
2738
  break;
@@ -2364,6 +2749,7 @@ var CimplifyElements = class {
2364
2749
  this.addressData = null;
2365
2750
  this.paymentData = null;
2366
2751
  this.checkoutInProgress = false;
2752
+ this.authInProgress = false;
2367
2753
  this.activeCheckoutAbort = null;
2368
2754
  this.businessIdResolvePromise = null;
2369
2755
  this.client = client;
@@ -2522,7 +2908,6 @@ var CimplifyElements = class {
2522
2908
  customer_id: this.customerId ?? void 0
2523
2909
  };
2524
2910
  const timeoutMs = options.timeout_ms ?? 18e4;
2525
- const paymentWindow = checkoutElement.getContentWindow();
2526
2911
  return new Promise((resolve) => {
2527
2912
  let settled = false;
2528
2913
  const cleanup = () => {
@@ -2558,18 +2943,7 @@ var CimplifyElements = class {
2558
2943
  if (!message) {
2559
2944
  return;
2560
2945
  }
2561
- if (message.type === MESSAGE_TYPES.LOGOUT_COMPLETE) {
2562
- checkoutElement.sendMessage({ type: MESSAGE_TYPES.ABORT_CHECKOUT });
2563
- settle(
2564
- toCheckoutError(
2565
- "AUTH_LOST",
2566
- "Authentication was cleared during checkout.",
2567
- true
2568
- )
2569
- );
2570
- return;
2571
- }
2572
- if (paymentWindow && event.source && event.source !== paymentWindow) {
2946
+ if (!checkoutElement._acceptsMessageEvent(event, message)) {
2573
2947
  return;
2574
2948
  }
2575
2949
  if (message.type === MESSAGE_TYPES.CHECKOUT_STATUS) {
@@ -2585,6 +2959,16 @@ var CimplifyElements = class {
2585
2959
  enrolled_in_link: message.enrolled_in_link
2586
2960
  });
2587
2961
  }
2962
+ if (message.type === MESSAGE_TYPES.LOGOUT_COMPLETE) {
2963
+ checkoutElement.sendMessage({ type: MESSAGE_TYPES.ABORT_CHECKOUT });
2964
+ settle(
2965
+ toCheckoutError(
2966
+ "AUTH_LOST",
2967
+ "Authentication was cleared during checkout.",
2968
+ true
2969
+ )
2970
+ );
2971
+ }
2588
2972
  };
2589
2973
  if (typeof window !== "undefined") {
2590
2974
  window.addEventListener("message", handleCheckoutMessage);
@@ -2644,12 +3028,7 @@ var CimplifyElements = class {
2644
3028
  return this.options.appearance;
2645
3029
  }
2646
3030
  async hydrateCustomerData() {
2647
- if (!this.accessToken || this.customerData) {
2648
- return;
2649
- }
2650
- if (!this.client.getAccessToken()) {
2651
- this.client.setAccessToken(this.accessToken);
2652
- }
3031
+ if (!this.accessToken || this.customerData) return;
2653
3032
  const linkDataResult = await this.client.link.getLinkData();
2654
3033
  if (!linkDataResult.ok || !linkDataResult.value?.customer) {
2655
3034
  return;
@@ -2660,6 +3039,85 @@ var CimplifyElements = class {
2660
3039
  email: customer.email || null,
2661
3040
  phone: customer.phone || null
2662
3041
  };
3042
+ this.customerId = customer.id;
3043
+ }
3044
+ sourceElementFor(event, message) {
3045
+ for (const element of this.elements.values()) {
3046
+ if (element._acceptsMessageEvent(event, message)) {
3047
+ return element;
3048
+ }
3049
+ }
3050
+ return null;
3051
+ }
3052
+ async applyAccessToken(token) {
3053
+ this.accessToken = token;
3054
+ this.accountId = decodeJwtSub(token);
3055
+ this.client.setAccessToken(token);
3056
+ await this.hydrateCustomerData();
3057
+ return {
3058
+ accountId: this.accountId ?? "",
3059
+ customerId: this.customerId ?? "",
3060
+ token,
3061
+ customer: this.customerData ?? { name: "", email: null, phone: null }
3062
+ };
3063
+ }
3064
+ broadcastAccessToken(token) {
3065
+ this.elements.forEach((element) => {
3066
+ element.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
3067
+ });
3068
+ }
3069
+ startEmbeddedAuth(sourceElement, request) {
3070
+ if (this.authInProgress) return;
3071
+ const auth = this.options.auth ?? {};
3072
+ const clientId = auth.clientId ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_CLIENT_ID");
3073
+ const redirectUri = auth.redirectUri ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_REDIRECT_URI");
3074
+ if (!clientId || !redirectUri) {
3075
+ sourceElement._emitError({
3076
+ code: "AUTH_CONFIG_REQUIRED",
3077
+ message: "Cimplify OAuth clientId and redirectUri are required."
3078
+ });
3079
+ return;
3080
+ }
3081
+ this.authInProgress = true;
3082
+ void startSignIn({
3083
+ clientId,
3084
+ redirectUri,
3085
+ callbackUri: auth.callbackUri,
3086
+ scope: auth.scope,
3087
+ issuer: auth.issuer,
3088
+ authUrl: auth.authUrl,
3089
+ loginHint: request.loginHint,
3090
+ prompt: request.prompt,
3091
+ uiMode: request.mode,
3092
+ mode: "modal",
3093
+ silentFirst: request.mode === ELEMENTS_AUTH_MODES.CHECKOUT && request.prompt !== ELEMENTS_AUTH_PROMPTS.LOGIN,
3094
+ onSuccess: async ({ accessToken }) => {
3095
+ this.authInProgress = false;
3096
+ if (!accessToken) {
3097
+ sourceElement._emitError({
3098
+ code: "AUTH_CALLBACK_MISSING_TOKEN",
3099
+ message: "Sign-in callback did not return an access token."
3100
+ });
3101
+ return;
3102
+ }
3103
+ const data = await this.applyAccessToken(accessToken);
3104
+ this.broadcastAccessToken(accessToken);
3105
+ sourceElement._emitAuthenticated(data);
3106
+ },
3107
+ onError: (err2) => {
3108
+ this.authInProgress = false;
3109
+ sourceElement._emitError({
3110
+ code: err2.error,
3111
+ message: err2.description ?? err2.error
3112
+ });
3113
+ }
3114
+ }).catch((error) => {
3115
+ this.authInProgress = false;
3116
+ sourceElement._emitError({
3117
+ code: "AUTH_START_FAILED",
3118
+ message: error instanceof Error ? error.message : "Unable to start sign-in."
3119
+ });
3120
+ });
2663
3121
  }
2664
3122
  handleMessage(event) {
2665
3123
  if (!isAllowedOrigin(event.origin)) {
@@ -2667,26 +3125,11 @@ var CimplifyElements = class {
2667
3125
  }
2668
3126
  const message = parseIframeMessage(event.data);
2669
3127
  if (!message) return;
3128
+ const sourceElement = this.sourceElementFor(event, message);
3129
+ if (!sourceElement) return;
2670
3130
  switch (message.type) {
2671
- case MESSAGE_TYPES.AUTHENTICATED:
2672
- const customer = message.customer ?? {
2673
- name: "",
2674
- email: null,
2675
- phone: null
2676
- };
2677
- this.accessToken = message.token;
2678
- this.accountId = message.accountId;
2679
- this.customerId = message.customerId;
2680
- this.customerData = customer;
2681
- this.client.setAccessToken(message.token);
2682
- this.elements.forEach((element, type) => {
2683
- if (type !== ELEMENT_TYPES.AUTH && type !== ELEMENT_TYPES.CHECKOUT) {
2684
- element.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token: message.token });
2685
- }
2686
- });
2687
- break;
2688
- case MESSAGE_TYPES.TOKEN_REFRESHED:
2689
- this.accessToken = message.token;
3131
+ case MESSAGE_TYPES.AUTH_REQUESTED:
3132
+ this.startEmbeddedAuth(sourceElement, message);
2690
3133
  break;
2691
3134
  case MESSAGE_TYPES.ADDRESS_CHANGED:
2692
3135
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -2856,6 +3299,17 @@ var CimplifyElement = class {
2856
3299
  isMounted() {
2857
3300
  return this.mounted && Boolean(this.iframe) && this.iframe?.isConnected === true;
2858
3301
  }
3302
+ _acceptsMessageEvent(event, message) {
3303
+ const iframeWindow = this.iframe?.contentWindow;
3304
+ if (!iframeWindow || event.source !== iframeWindow) return false;
3305
+ return message.nonce === this.nonce;
3306
+ }
3307
+ _emitAuthenticated(data) {
3308
+ this.emit(EVENT_TYPES.AUTHENTICATED, data);
3309
+ }
3310
+ _emitError(error) {
3311
+ this.emit(EVENT_TYPES.ERROR, error);
3312
+ }
2859
3313
  async createIframe() {
2860
3314
  if (!this.container) return;
2861
3315
  const resolvedBusinessId = this.businessId ?? await this.parent.resolveBusinessId();
@@ -2899,17 +3353,9 @@ var CimplifyElement = class {
2899
3353
  if (!isAllowedOrigin(event.origin)) {
2900
3354
  return;
2901
3355
  }
2902
- const data = event.data;
2903
- if (data?.nonce) {
2904
- if (data.nonce !== this.nonce) return;
2905
- } else {
2906
- const iframeWindow = this.iframe?.contentWindow;
2907
- if (iframeWindow && event.source && event.source !== iframeWindow) {
2908
- return;
2909
- }
2910
- }
2911
3356
  const message = parseIframeMessage(event.data);
2912
3357
  if (!message) return;
3358
+ if (!this._acceptsMessageEvent(event, message)) return;
2913
3359
  switch (message.type) {
2914
3360
  case MESSAGE_TYPES.READY:
2915
3361
  this.ready = true;
@@ -2928,7 +3374,7 @@ var CimplifyElement = class {
2928
3374
  submitLabel: this.options.submitLabel
2929
3375
  });
2930
3376
  const token = this.parent.getAccessToken();
2931
- if (token && this.type !== ELEMENT_TYPES.AUTH) {
3377
+ if (token) {
2932
3378
  this.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
2933
3379
  }
2934
3380
  this.pendingInit = null;
@@ -2939,22 +3385,6 @@ var CimplifyElement = class {
2939
3385
  case MESSAGE_TYPES.HEIGHT_CHANGE:
2940
3386
  if (this.iframe) this.iframe.style.height = `${message.height}px`;
2941
3387
  break;
2942
- case MESSAGE_TYPES.AUTHENTICATED:
2943
- const customer = message.customer ?? {
2944
- name: "",
2945
- email: null,
2946
- phone: null
2947
- };
2948
- this.emit(EVENT_TYPES.AUTHENTICATED, {
2949
- accountId: message.accountId,
2950
- customerId: message.customerId,
2951
- token: message.token,
2952
- customer
2953
- });
2954
- break;
2955
- case MESSAGE_TYPES.REQUIRES_OTP:
2956
- this.emit(EVENT_TYPES.REQUIRES_OTP, { contactMasked: message.contactMasked });
2957
- break;
2958
3388
  case MESSAGE_TYPES.ERROR:
2959
3389
  this.emit(EVENT_TYPES.ERROR, { code: message.code, message: message.message });
2960
3390
  break;
@@ -3010,7 +3440,11 @@ exports.CimplifyElement = CimplifyElement;
3010
3440
  exports.CimplifyElements = CimplifyElements;
3011
3441
  exports.DEFAULT_COUNTRY = DEFAULT_COUNTRY;
3012
3442
  exports.DEFAULT_CURRENCY = DEFAULT_CURRENCY;
3443
+ exports.DEFAULT_ISSUER = DEFAULT_ISSUER;
3013
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;
3014
3448
  exports.ELEMENT_TYPES = ELEMENT_TYPES;
3015
3449
  exports.EVENT_TYPES = EVENT_TYPES;
3016
3450
  exports.FxService = FxService;
@@ -3028,14 +3462,20 @@ exports.PAYMENT_METHOD = PAYMENT_METHOD;
3028
3462
  exports.PAYMENT_MUTATION = PAYMENT_MUTATION;
3029
3463
  exports.PAYMENT_STATE = PAYMENT_STATE;
3030
3464
  exports.PICKUP_TIME_TYPE = PICKUP_TIME_TYPE;
3465
+ exports.PKCE_COOKIE = PKCE_COOKIE;
3466
+ exports.PKCE_COOKIE_PATH = PKCE_COOKIE_PATH;
3031
3467
  exports.SchedulingService = SchedulingService;
3032
3468
  exports.combine = combine;
3033
3469
  exports.combineObject = combineObject;
3034
3470
  exports.createElements = createElements;
3471
+ exports.decodePkceState = decodePkceState;
3035
3472
  exports.err = err;
3036
3473
  exports.flatMap = flatMap;
3037
3474
  exports.fromPromise = fromPromise;
3038
3475
  exports.generateIdempotencyKey = generateIdempotencyKey;
3476
+ exports.generatePkce = generatePkce;
3477
+ exports.generateState = generateState;
3478
+ exports.getAuthorizationEndpoint = getAuthorizationEndpoint;
3039
3479
  exports.getOrElse = getOrElse;
3040
3480
  exports.isErr = isErr;
3041
3481
  exports.isOk = isOk;
@@ -3043,6 +3483,7 @@ exports.mapError = mapError;
3043
3483
  exports.mapResult = mapResult;
3044
3484
  exports.ok = ok;
3045
3485
  exports.safe = safe;
3486
+ exports.startSignIn = startSignIn;
3046
3487
  exports.toNullable = toNullable;
3047
3488
  exports.tryCatch = tryCatch;
3048
3489
  exports.unwrap = unwrap;