@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
@@ -1756,8 +1756,20 @@ var LinkService = class {
1756
1756
  }
1757
1757
  async verifyOtp(input, opts) {
1758
1758
  const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
1759
+ const { business_id: _ignoredBusinessId, ...body } = input;
1759
1760
  const result = await safe(
1760
- this.client.linkPost("/v1/link/auth/verify-otp", input, { idempotencyKey })
1761
+ this.client.linkPost("/v1/link/auth/verify-otp", body, { idempotencyKey })
1762
+ );
1763
+ if (result.ok && result.value.session_token) {
1764
+ this.client.setAccessToken(result.value.session_token);
1765
+ }
1766
+ return result;
1767
+ }
1768
+ async refreshSession(sessionToken, opts) {
1769
+ const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
1770
+ const body = sessionToken ? { session_token: sessionToken } : {};
1771
+ const result = await safe(
1772
+ this.client.linkPost("/v1/link/auth/refresh", body, { idempotencyKey })
1761
1773
  );
1762
1774
  if (result.ok && result.value.session_token) {
1763
1775
  this.client.setAccessToken(result.value.session_token);
@@ -2239,30 +2251,39 @@ var MESSAGE_TYPES = {
2239
2251
  SET_TOKEN: "set_token",
2240
2252
  SET_CART: "set_cart",
2241
2253
  GET_DATA: "get_data",
2254
+ NAVIGATE: "navigate",
2242
2255
  REFRESH_TOKEN: "refresh_token",
2243
2256
  LOGOUT: "logout",
2244
2257
  PROCESS_CHECKOUT: "process_checkout",
2245
2258
  ABORT_CHECKOUT: "abort_checkout",
2246
2259
  READY: "ready",
2247
2260
  HEIGHT_CHANGE: "height_change",
2248
- AUTHENTICATED: "authenticated",
2249
- REQUIRES_OTP: "requires_otp",
2250
2261
  ERROR: "error",
2251
2262
  ADDRESS_CHANGED: "address_changed",
2252
2263
  ADDRESS_SELECTED: "address_selected",
2253
2264
  PAYMENT_METHOD_SELECTED: "payment_method_selected",
2254
- TOKEN_REFRESHED: "token_refreshed",
2255
2265
  LOGOUT_COMPLETE: "logout_complete",
2266
+ AUTH_REQUESTED: "auth_requested",
2256
2267
  CONTACT_PROVIDED: "contact_provided",
2257
2268
  CHECKOUT_STATUS: "checkout_status",
2258
2269
  CHECKOUT_COMPLETE: "checkout_complete",
2259
2270
  ORDER_TYPE_CHANGED: "order_type_changed",
2260
2271
  REQUEST_SUBMIT: "request_submit"
2261
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
+ };
2262
2284
  var EVENT_TYPES = {
2263
2285
  READY: "ready",
2264
2286
  AUTHENTICATED: "authenticated",
2265
- REQUIRES_OTP: "requires_otp",
2266
2287
  ERROR: "error",
2267
2288
  CHANGE: "change",
2268
2289
  BLUR: "blur",
@@ -2271,6 +2292,326 @@ var EVENT_TYPES = {
2271
2292
  REQUEST_SUBMIT: "request_submit"
2272
2293
  };
2273
2294
 
2295
+ // src/internal/pkce.ts
2296
+ var VERIFIER_BYTES = 64;
2297
+ async function generatePkce() {
2298
+ const random = new Uint8Array(VERIFIER_BYTES);
2299
+ crypto.getRandomValues(random);
2300
+ const verifier = base64UrlEncode(random);
2301
+ const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
2302
+ const challenge = base64UrlEncode(new Uint8Array(digest));
2303
+ return { verifier, challenge, method: "S256" };
2304
+ }
2305
+ function generateState(byteLength = 16) {
2306
+ const buf = new Uint8Array(byteLength);
2307
+ crypto.getRandomValues(buf);
2308
+ return base64UrlEncode(buf);
2309
+ }
2310
+ function base64UrlEncode(bytes) {
2311
+ let str = "";
2312
+ for (const byte of bytes) str += String.fromCharCode(byte);
2313
+ return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
2314
+ }
2315
+
2316
+ // src/internal/pkce-cookie.ts
2317
+ var PKCE_COOKIE = "cimplify_pkce";
2318
+ var PKCE_COOKIE_PATH = "/auth";
2319
+ var PKCE_COOKIE_MAX_AGE_SECONDS = 600;
2320
+ function encodePkceState(state) {
2321
+ return encodeURIComponent(JSON.stringify(state));
2322
+ }
2323
+ function decodePkceState(raw) {
2324
+ try {
2325
+ const parsed = JSON.parse(decodeURIComponent(raw));
2326
+ if (typeof parsed?.verifier === "string" && typeof parsed.state === "string" && typeof parsed.returnTo === "string") {
2327
+ return { verifier: parsed.verifier, state: parsed.state, returnTo: parsed.returnTo };
2328
+ }
2329
+ } catch {
2330
+ }
2331
+ return null;
2332
+ }
2333
+
2334
+ // src/internal/discovery.ts
2335
+ var DEFAULT_ISSUER = "https://api.cimplify.io";
2336
+ var DEFAULT_AUTHORIZATION_ENDPOINT = "https://auth.cimplify.io/oauth/authorize";
2337
+ function fallbackAuthorizationEndpoint(issuerBase) {
2338
+ if (issuerBase === DEFAULT_ISSUER) return DEFAULT_AUTHORIZATION_ENDPOINT;
2339
+ throw new Error(
2340
+ `OIDC discovery for "${issuerBase}" is unreachable and no fallback authorize endpoint is known for it. Make discovery reachable (enable CORS) or pass authUrl.`
2341
+ );
2342
+ }
2343
+ var cache = /* @__PURE__ */ new Map();
2344
+ function fetchDiscovery(issuer) {
2345
+ const base = issuer.replace(/\/$/, "");
2346
+ let pending = cache.get(base);
2347
+ if (!pending) {
2348
+ pending = fetch(`${base}/.well-known/openid-configuration`).then((res) => {
2349
+ if (!res.ok) throw new Error(`oidc discovery failed: ${res.status}`);
2350
+ return res.json();
2351
+ });
2352
+ pending.catch(() => cache.delete(base));
2353
+ cache.set(base, pending);
2354
+ }
2355
+ return pending;
2356
+ }
2357
+ async function getAuthorizationEndpoint(issuer) {
2358
+ const base = issuer.replace(/\/$/, "");
2359
+ try {
2360
+ const doc = await fetchDiscovery(base);
2361
+ if (doc.authorization_endpoint) return doc.authorization_endpoint;
2362
+ } catch {
2363
+ }
2364
+ return fallbackAuthorizationEndpoint(base);
2365
+ }
2366
+
2367
+ // src/internal/modal-iframe.ts
2368
+ function openModalIframe(opts) {
2369
+ const overlay = document.createElement("div");
2370
+ overlay.dataset.cimplifyModal = "1";
2371
+ Object.assign(overlay.style, {
2372
+ position: "fixed",
2373
+ inset: "0",
2374
+ background: "rgba(15, 18, 24, 0.55)",
2375
+ zIndex: "2147483647",
2376
+ display: "grid",
2377
+ placeItems: "center",
2378
+ backdropFilter: "blur(2px)"
2379
+ });
2380
+ const card = document.createElement("div");
2381
+ Object.assign(card.style, {
2382
+ width: `${opts.width ?? 480}px`,
2383
+ maxWidth: "calc(100vw - 24px)",
2384
+ height: `${opts.height ?? 720}px`,
2385
+ maxHeight: "calc(100vh - 32px)"
2386
+ });
2387
+ const iframe = document.createElement("iframe");
2388
+ iframe.src = opts.src;
2389
+ iframe.style.width = "100%";
2390
+ iframe.style.height = "100%";
2391
+ iframe.style.border = "none";
2392
+ iframe.style.background = "transparent";
2393
+ iframe.setAttribute(
2394
+ "sandbox",
2395
+ opts.sandbox ?? "allow-scripts allow-same-origin allow-forms allow-popups"
2396
+ );
2397
+ iframe.setAttribute("allow", "publickey-credentials-get; publickey-credentials-create");
2398
+ card.appendChild(iframe);
2399
+ overlay.appendChild(card);
2400
+ document.body.appendChild(overlay);
2401
+ const close = () => {
2402
+ overlay.remove();
2403
+ document.removeEventListener("keydown", onKey);
2404
+ opts.onClose?.();
2405
+ };
2406
+ const onKey = (e) => {
2407
+ if (e.key === "Escape") close();
2408
+ };
2409
+ overlay.addEventListener("click", (e) => {
2410
+ if (e.target === overlay) close();
2411
+ });
2412
+ document.addEventListener("keydown", onKey);
2413
+ return { iframe, close };
2414
+ }
2415
+
2416
+ // src/sign-in.ts
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
+ }
2531
+ function resolveAuthorizeEndpoint(opts) {
2532
+ if (opts.authUrl) {
2533
+ return Promise.resolve(`${opts.authUrl.replace(/\/$/, "")}/oauth/authorize`);
2534
+ }
2535
+ return getAuthorizationEndpoint(opts.issuer ?? DEFAULT_ISSUER);
2536
+ }
2537
+ async function startSignIn(opts) {
2538
+ const callbackUri = opts.callbackUri ?? "/auth/callback";
2539
+ const pkce = await generatePkce();
2540
+ const state = generateState();
2541
+ const authorizeEndpoint = await resolveAuthorizeEndpoint(opts);
2542
+ if ((opts.mode ?? "redirect") === "redirect") {
2543
+ startRedirectSignIn(opts, authorizeEndpoint, pkce, state);
2544
+ return;
2545
+ }
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
2555
+ });
2556
+ const expectedOrigin = new URL(authorizeEndpoint).origin;
2557
+ let completed = false;
2558
+ let handler = () => {
2559
+ };
2560
+ const modal = openModalIframe({
2561
+ src,
2562
+ onClose: () => {
2563
+ window.removeEventListener("message", handler);
2564
+ if (!completed) {
2565
+ opts.onError?.({ error: ERROR_CANCELLED });
2566
+ }
2567
+ }
2568
+ });
2569
+ handler = async (event) => {
2570
+ if (event.origin !== expectedOrigin) return;
2571
+ const data = event.data;
2572
+ if (!data || typeof data !== "object" || data.type !== AUTHORIZATION_RESPONSE_MESSAGE_TYPE) return;
2573
+ const response = data.response;
2574
+ if (response.error) {
2575
+ completed = true;
2576
+ modal.close();
2577
+ opts.onError?.({ error: response.error, description: response.error_description });
2578
+ return;
2579
+ }
2580
+ if (!response.code) return;
2581
+ if (response.state !== state) {
2582
+ completed = true;
2583
+ modal.close();
2584
+ opts.onError?.({ error: ERROR_STATE_MISMATCH });
2585
+ return;
2586
+ }
2587
+ try {
2588
+ const result = await exchangeAuthorizationCode(callbackUri, pkce, state, response.code);
2589
+ completed = true;
2590
+ modal.close();
2591
+ opts.onSuccess?.(result);
2592
+ } catch (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
+ });
2599
+ modal.close();
2600
+ }
2601
+ };
2602
+ window.addEventListener("message", handler);
2603
+ }
2604
+ function startRedirectSignIn(opts, authorizeEndpoint, pkce, state) {
2605
+ const returnTo = opts.returnTo ?? window.location.pathname + window.location.search;
2606
+ const cookieValue = encodePkceState({ verifier: pkce.verifier, state, returnTo });
2607
+ const secure = window.location.protocol === "https:" ? "; Secure" : "";
2608
+ document.cookie = `${PKCE_COOKIE}=${cookieValue}; Path=${PKCE_COOKIE_PATH}; Max-Age=${PKCE_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secure}`;
2609
+ window.location.assign(buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
2610
+ responseMode: RESPONSE_MODE_QUERY,
2611
+ prompt: opts.prompt
2612
+ }));
2613
+ }
2614
+
2274
2615
  // src/elements.ts
2275
2616
  function toCheckoutError(code, message, recoverable) {
2276
2617
  const hint = getErrorHint(code);
@@ -2286,12 +2627,36 @@ function toCheckoutError(code, message, recoverable) {
2286
2627
  };
2287
2628
  }
2288
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));
2289
2633
  function generateNonce() {
2290
2634
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
2291
2635
  return crypto.randomUUID().replace(/-/g, "").slice(0, 16);
2292
2636
  }
2293
2637
  return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
2294
2638
  }
2639
+ function readPublicEnv(name) {
2640
+ try {
2641
+ const processLike = globalThis.process;
2642
+ const value = processLike?.env?.[name];
2643
+ return value && value.trim() ? value : void 0;
2644
+ } catch {
2645
+ return void 0;
2646
+ }
2647
+ }
2648
+ function decodeJwtSub(token) {
2649
+ const [, payload] = token.split(".");
2650
+ if (!payload || typeof atob === "undefined") return "";
2651
+ try {
2652
+ const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
2653
+ const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
2654
+ const parsed = JSON.parse(atob(padded));
2655
+ return typeof parsed.sub === "string" ? parsed.sub : "";
2656
+ } catch {
2657
+ return "";
2658
+ }
2659
+ }
2295
2660
  function isAllowedOrigin(origin) {
2296
2661
  try {
2297
2662
  const url = new URL(origin);
@@ -2307,7 +2672,21 @@ function isAllowedOrigin(origin) {
2307
2672
  return false;
2308
2673
  }
2309
2674
  }
2310
- var KNOWN_IFRAME_TYPES = new Set(Object.values(MESSAGE_TYPES));
2675
+ var KNOWN_IFRAME_TYPES = /* @__PURE__ */ new Set([
2676
+ MESSAGE_TYPES.READY,
2677
+ MESSAGE_TYPES.HEIGHT_CHANGE,
2678
+ MESSAGE_TYPES.AUTH_REQUESTED,
2679
+ MESSAGE_TYPES.ERROR,
2680
+ MESSAGE_TYPES.ADDRESS_CHANGED,
2681
+ MESSAGE_TYPES.ADDRESS_SELECTED,
2682
+ MESSAGE_TYPES.PAYMENT_METHOD_SELECTED,
2683
+ MESSAGE_TYPES.CONTACT_PROVIDED,
2684
+ MESSAGE_TYPES.LOGOUT_COMPLETE,
2685
+ MESSAGE_TYPES.CHECKOUT_STATUS,
2686
+ MESSAGE_TYPES.CHECKOUT_COMPLETE,
2687
+ MESSAGE_TYPES.ORDER_TYPE_CHANGED,
2688
+ MESSAGE_TYPES.REQUEST_SUBMIT
2689
+ ]);
2311
2690
  function parseIframeMessage(data) {
2312
2691
  if (!data || typeof data !== "object") {
2313
2692
  return null;
@@ -2317,11 +2696,17 @@ function parseIframeMessage(data) {
2317
2696
  return null;
2318
2697
  }
2319
2698
  switch (record.type) {
2320
- case MESSAGE_TYPES.AUTHENTICATED:
2321
- if (typeof record.token !== "string") return null;
2322
- break;
2323
- case MESSAGE_TYPES.TOKEN_REFRESHED:
2324
- if (typeof record.token !== "string") return null;
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
+ }
2325
2710
  break;
2326
2711
  case MESSAGE_TYPES.ADDRESS_CHANGED:
2327
2712
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -2339,13 +2724,13 @@ function parseIframeMessage(data) {
2339
2724
  case MESSAGE_TYPES.CHECKOUT_COMPLETE:
2340
2725
  if (typeof record.success !== "boolean") return null;
2341
2726
  break;
2727
+ case MESSAGE_TYPES.CHECKOUT_STATUS:
2728
+ if (typeof record.status !== "string" || !record.context || typeof record.context !== "object") return null;
2729
+ break;
2342
2730
  case MESSAGE_TYPES.READY:
2343
2731
  case MESSAGE_TYPES.HEIGHT_CHANGE:
2344
2732
  if (typeof record.height !== "number") return null;
2345
2733
  break;
2346
- case MESSAGE_TYPES.REQUIRES_OTP:
2347
- if (typeof record.contactMasked !== "string") return null;
2348
- break;
2349
2734
  case MESSAGE_TYPES.ORDER_TYPE_CHANGED:
2350
2735
  if (typeof record.orderType !== "string") return null;
2351
2736
  break;
@@ -2362,6 +2747,7 @@ var CimplifyElements = class {
2362
2747
  this.addressData = null;
2363
2748
  this.paymentData = null;
2364
2749
  this.checkoutInProgress = false;
2750
+ this.authInProgress = false;
2365
2751
  this.activeCheckoutAbort = null;
2366
2752
  this.businessIdResolvePromise = null;
2367
2753
  this.client = client;
@@ -2520,7 +2906,6 @@ var CimplifyElements = class {
2520
2906
  customer_id: this.customerId ?? void 0
2521
2907
  };
2522
2908
  const timeoutMs = options.timeout_ms ?? 18e4;
2523
- const paymentWindow = checkoutElement.getContentWindow();
2524
2909
  return new Promise((resolve) => {
2525
2910
  let settled = false;
2526
2911
  const cleanup = () => {
@@ -2556,18 +2941,7 @@ var CimplifyElements = class {
2556
2941
  if (!message) {
2557
2942
  return;
2558
2943
  }
2559
- if (message.type === MESSAGE_TYPES.LOGOUT_COMPLETE) {
2560
- checkoutElement.sendMessage({ type: MESSAGE_TYPES.ABORT_CHECKOUT });
2561
- settle(
2562
- toCheckoutError(
2563
- "AUTH_LOST",
2564
- "Authentication was cleared during checkout.",
2565
- true
2566
- )
2567
- );
2568
- return;
2569
- }
2570
- if (paymentWindow && event.source && event.source !== paymentWindow) {
2944
+ if (!checkoutElement._acceptsMessageEvent(event, message)) {
2571
2945
  return;
2572
2946
  }
2573
2947
  if (message.type === MESSAGE_TYPES.CHECKOUT_STATUS) {
@@ -2583,6 +2957,16 @@ var CimplifyElements = class {
2583
2957
  enrolled_in_link: message.enrolled_in_link
2584
2958
  });
2585
2959
  }
2960
+ if (message.type === MESSAGE_TYPES.LOGOUT_COMPLETE) {
2961
+ checkoutElement.sendMessage({ type: MESSAGE_TYPES.ABORT_CHECKOUT });
2962
+ settle(
2963
+ toCheckoutError(
2964
+ "AUTH_LOST",
2965
+ "Authentication was cleared during checkout.",
2966
+ true
2967
+ )
2968
+ );
2969
+ }
2586
2970
  };
2587
2971
  if (typeof window !== "undefined") {
2588
2972
  window.addEventListener("message", handleCheckoutMessage);
@@ -2642,12 +3026,7 @@ var CimplifyElements = class {
2642
3026
  return this.options.appearance;
2643
3027
  }
2644
3028
  async hydrateCustomerData() {
2645
- if (!this.accessToken || this.customerData) {
2646
- return;
2647
- }
2648
- if (!this.client.getAccessToken()) {
2649
- this.client.setAccessToken(this.accessToken);
2650
- }
3029
+ if (!this.accessToken || this.customerData) return;
2651
3030
  const linkDataResult = await this.client.link.getLinkData();
2652
3031
  if (!linkDataResult.ok || !linkDataResult.value?.customer) {
2653
3032
  return;
@@ -2658,6 +3037,85 @@ var CimplifyElements = class {
2658
3037
  email: customer.email || null,
2659
3038
  phone: customer.phone || null
2660
3039
  };
3040
+ this.customerId = customer.id;
3041
+ }
3042
+ sourceElementFor(event, message) {
3043
+ for (const element of this.elements.values()) {
3044
+ if (element._acceptsMessageEvent(event, message)) {
3045
+ return element;
3046
+ }
3047
+ }
3048
+ return null;
3049
+ }
3050
+ async applyAccessToken(token) {
3051
+ this.accessToken = token;
3052
+ this.accountId = decodeJwtSub(token);
3053
+ this.client.setAccessToken(token);
3054
+ await this.hydrateCustomerData();
3055
+ return {
3056
+ accountId: this.accountId ?? "",
3057
+ customerId: this.customerId ?? "",
3058
+ token,
3059
+ customer: this.customerData ?? { name: "", email: null, phone: null }
3060
+ };
3061
+ }
3062
+ broadcastAccessToken(token) {
3063
+ this.elements.forEach((element) => {
3064
+ element.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
3065
+ });
3066
+ }
3067
+ startEmbeddedAuth(sourceElement, request) {
3068
+ if (this.authInProgress) return;
3069
+ const auth = this.options.auth ?? {};
3070
+ const clientId = auth.clientId ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_CLIENT_ID");
3071
+ const redirectUri = auth.redirectUri ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_REDIRECT_URI");
3072
+ if (!clientId || !redirectUri) {
3073
+ sourceElement._emitError({
3074
+ code: "AUTH_CONFIG_REQUIRED",
3075
+ message: "Cimplify OAuth clientId and redirectUri are required."
3076
+ });
3077
+ return;
3078
+ }
3079
+ this.authInProgress = true;
3080
+ void startSignIn({
3081
+ clientId,
3082
+ redirectUri,
3083
+ callbackUri: auth.callbackUri,
3084
+ scope: auth.scope,
3085
+ issuer: auth.issuer,
3086
+ authUrl: auth.authUrl,
3087
+ loginHint: request.loginHint,
3088
+ prompt: request.prompt,
3089
+ uiMode: request.mode,
3090
+ mode: "modal",
3091
+ silentFirst: request.mode === ELEMENTS_AUTH_MODES.CHECKOUT && request.prompt !== ELEMENTS_AUTH_PROMPTS.LOGIN,
3092
+ onSuccess: async ({ accessToken }) => {
3093
+ this.authInProgress = false;
3094
+ if (!accessToken) {
3095
+ sourceElement._emitError({
3096
+ code: "AUTH_CALLBACK_MISSING_TOKEN",
3097
+ message: "Sign-in callback did not return an access token."
3098
+ });
3099
+ return;
3100
+ }
3101
+ const data = await this.applyAccessToken(accessToken);
3102
+ this.broadcastAccessToken(accessToken);
3103
+ sourceElement._emitAuthenticated(data);
3104
+ },
3105
+ onError: (err2) => {
3106
+ this.authInProgress = false;
3107
+ sourceElement._emitError({
3108
+ code: err2.error,
3109
+ message: err2.description ?? err2.error
3110
+ });
3111
+ }
3112
+ }).catch((error) => {
3113
+ this.authInProgress = false;
3114
+ sourceElement._emitError({
3115
+ code: "AUTH_START_FAILED",
3116
+ message: error instanceof Error ? error.message : "Unable to start sign-in."
3117
+ });
3118
+ });
2661
3119
  }
2662
3120
  handleMessage(event) {
2663
3121
  if (!isAllowedOrigin(event.origin)) {
@@ -2665,26 +3123,11 @@ var CimplifyElements = class {
2665
3123
  }
2666
3124
  const message = parseIframeMessage(event.data);
2667
3125
  if (!message) return;
3126
+ const sourceElement = this.sourceElementFor(event, message);
3127
+ if (!sourceElement) return;
2668
3128
  switch (message.type) {
2669
- case MESSAGE_TYPES.AUTHENTICATED:
2670
- const customer = message.customer ?? {
2671
- name: "",
2672
- email: null,
2673
- phone: null
2674
- };
2675
- this.accessToken = message.token;
2676
- this.accountId = message.accountId;
2677
- this.customerId = message.customerId;
2678
- this.customerData = customer;
2679
- this.client.setAccessToken(message.token);
2680
- this.elements.forEach((element, type) => {
2681
- if (type !== ELEMENT_TYPES.AUTH && type !== ELEMENT_TYPES.CHECKOUT) {
2682
- element.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token: message.token });
2683
- }
2684
- });
2685
- break;
2686
- case MESSAGE_TYPES.TOKEN_REFRESHED:
2687
- this.accessToken = message.token;
3129
+ case MESSAGE_TYPES.AUTH_REQUESTED:
3130
+ this.startEmbeddedAuth(sourceElement, message);
2688
3131
  break;
2689
3132
  case MESSAGE_TYPES.ADDRESS_CHANGED:
2690
3133
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -2854,6 +3297,17 @@ var CimplifyElement = class {
2854
3297
  isMounted() {
2855
3298
  return this.mounted && Boolean(this.iframe) && this.iframe?.isConnected === true;
2856
3299
  }
3300
+ _acceptsMessageEvent(event, message) {
3301
+ const iframeWindow = this.iframe?.contentWindow;
3302
+ if (!iframeWindow || event.source !== iframeWindow) return false;
3303
+ return message.nonce === this.nonce;
3304
+ }
3305
+ _emitAuthenticated(data) {
3306
+ this.emit(EVENT_TYPES.AUTHENTICATED, data);
3307
+ }
3308
+ _emitError(error) {
3309
+ this.emit(EVENT_TYPES.ERROR, error);
3310
+ }
2857
3311
  async createIframe() {
2858
3312
  if (!this.container) return;
2859
3313
  const resolvedBusinessId = this.businessId ?? await this.parent.resolveBusinessId();
@@ -2897,17 +3351,9 @@ var CimplifyElement = class {
2897
3351
  if (!isAllowedOrigin(event.origin)) {
2898
3352
  return;
2899
3353
  }
2900
- const data = event.data;
2901
- if (data?.nonce) {
2902
- if (data.nonce !== this.nonce) return;
2903
- } else {
2904
- const iframeWindow = this.iframe?.contentWindow;
2905
- if (iframeWindow && event.source && event.source !== iframeWindow) {
2906
- return;
2907
- }
2908
- }
2909
3354
  const message = parseIframeMessage(event.data);
2910
3355
  if (!message) return;
3356
+ if (!this._acceptsMessageEvent(event, message)) return;
2911
3357
  switch (message.type) {
2912
3358
  case MESSAGE_TYPES.READY:
2913
3359
  this.ready = true;
@@ -2926,7 +3372,7 @@ var CimplifyElement = class {
2926
3372
  submitLabel: this.options.submitLabel
2927
3373
  });
2928
3374
  const token = this.parent.getAccessToken();
2929
- if (token && this.type !== ELEMENT_TYPES.AUTH) {
3375
+ if (token) {
2930
3376
  this.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
2931
3377
  }
2932
3378
  this.pendingInit = null;
@@ -2937,22 +3383,6 @@ var CimplifyElement = class {
2937
3383
  case MESSAGE_TYPES.HEIGHT_CHANGE:
2938
3384
  if (this.iframe) this.iframe.style.height = `${message.height}px`;
2939
3385
  break;
2940
- case MESSAGE_TYPES.AUTHENTICATED:
2941
- const customer = message.customer ?? {
2942
- name: "",
2943
- email: null,
2944
- phone: null
2945
- };
2946
- this.emit(EVENT_TYPES.AUTHENTICATED, {
2947
- accountId: message.accountId,
2948
- customerId: message.customerId,
2949
- token: message.token,
2950
- customer
2951
- });
2952
- break;
2953
- case MESSAGE_TYPES.REQUIRES_OTP:
2954
- this.emit(EVENT_TYPES.REQUIRES_OTP, { contactMasked: message.contactMasked });
2955
- break;
2956
3386
  case MESSAGE_TYPES.ERROR:
2957
3387
  this.emit(EVENT_TYPES.ERROR, { code: message.code, message: message.message });
2958
3388
  break;
@@ -2993,4 +3423,4 @@ function createElements(client, businessId, options) {
2993
3423
  return new CimplifyElements(client, businessId, options);
2994
3424
  }
2995
3425
 
2996
- export { AUTHORIZATION_TYPE, AUTH_MUTATION, AuthService, BusinessService, CHECKOUT_MODE, CHECKOUT_MUTATION, CHECKOUT_STEP, CONTACT_TYPE, CartOperations, CatalogueQueries, CheckoutService, CimplifyElement, CimplifyElements, DEFAULT_COUNTRY, DEFAULT_CURRENCY, 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, SchedulingService, combine, combineObject, createElements, err, flatMap, fromPromise, generateIdempotencyKey, getOrElse, isErr, isOk, mapError, mapResult, ok, safe, 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 };