@cimplify/sdk 0.65.0 → 0.67.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 (53) 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-AVQL3TSJ.js → chunk-3QSW33RG.js} +389 -78
  6. package/dist/chunk-E6T5VJMG.mjs +156 -0
  7. package/dist/{chunk-WDTFIIY6.mjs → chunk-FNK6UZOE.mjs} +2 -2
  8. package/dist/{chunk-3G4QCENX.mjs → chunk-FVGVJ4TC.mjs} +12 -50
  9. package/dist/chunk-IQLJJW2H.js +168 -0
  10. package/dist/{chunk-PKYZBKZD.mjs → chunk-JAPCAZN4.mjs} +10 -29
  11. package/dist/{chunk-R6363CC7.mjs → chunk-QQMDEGAK.mjs} +382 -79
  12. package/dist/{chunk-VKID3QUE.js → chunk-SH6HJW4A.js} +4 -4
  13. package/dist/{chunk-VAMZPBA4.js → chunk-SSLFZPAI.js} +44 -63
  14. package/dist/{chunk-HCZTBWU4.js → chunk-SXGFJEME.js} +12 -50
  15. package/dist/{client-BS5lNWWH.d.mts → client-ByI_3jfL.d.mts} +33 -20
  16. package/dist/{client-p1Iofyc9.d.ts → client-CQlEWH5j.d.ts} +1 -1
  17. package/dist/{client-QTrsv6Gu.d.ts → client-DVFQoDtI.d.ts} +33 -20
  18. package/dist/{client-XoswXzib.d.mts → client-Dd82KQ_G.d.mts} +1 -1
  19. package/dist/index.d.mts +2 -2
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +80 -81
  22. package/dist/index.mjs +4 -5
  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 +4 -7
  29. package/dist/react.d.ts +4 -7
  30. package/dist/react.js +63 -71
  31. package/dist/react.mjs +5 -13
  32. package/dist/server.d.mts +18 -3
  33. package/dist/server.d.ts +18 -3
  34. package/dist/server.js +175 -29
  35. package/dist/server.mjs +167 -25
  36. package/dist/{sign-in-dr7m09nm.d.ts → sign-in-RFuWZOgF.d.mts} +6 -1
  37. package/dist/{sign-in-dr7m09nm.d.mts → sign-in-RFuWZOgF.d.ts} +6 -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 +2 -2
  46. package/dist/testing.d.ts +2 -2
  47. package/dist/testing.js +79 -79
  48. package/dist/testing.mjs +5 -5
  49. package/package.json +1 -1
  50. package/dist/chunk-2AU263DK.mjs +0 -323
  51. package/dist/chunk-6DMHVQ42.js +0 -338
  52. package/dist/chunk-DKT62WQW.js +0 -53
  53. package/dist/chunk-XSOYJLMZ.mjs +0 -45
@@ -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,20 +2253,19 @@ 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",
@@ -2264,7 +2275,6 @@ var MESSAGE_TYPES = {
2264
2275
  var EVENT_TYPES = {
2265
2276
  READY: "ready",
2266
2277
  AUTHENTICATED: "authenticated",
2267
- REQUIRES_OTP: "requires_otp",
2268
2278
  ERROR: "error",
2269
2279
  CHANGE: "change",
2270
2280
  BLUR: "blur",
@@ -2273,6 +2283,227 @@ var EVENT_TYPES = {
2273
2283
  REQUEST_SUBMIT: "request_submit"
2274
2284
  };
2275
2285
 
2286
+ // src/internal/pkce.ts
2287
+ var VERIFIER_BYTES = 64;
2288
+ async function generatePkce() {
2289
+ const random = new Uint8Array(VERIFIER_BYTES);
2290
+ crypto.getRandomValues(random);
2291
+ const verifier = base64UrlEncode(random);
2292
+ const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
2293
+ const challenge = base64UrlEncode(new Uint8Array(digest));
2294
+ return { verifier, challenge, method: "S256" };
2295
+ }
2296
+ function generateState(byteLength = 16) {
2297
+ const buf = new Uint8Array(byteLength);
2298
+ crypto.getRandomValues(buf);
2299
+ return base64UrlEncode(buf);
2300
+ }
2301
+ function base64UrlEncode(bytes) {
2302
+ let str = "";
2303
+ for (const byte of bytes) str += String.fromCharCode(byte);
2304
+ return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
2305
+ }
2306
+
2307
+ // src/internal/pkce-cookie.ts
2308
+ var PKCE_COOKIE = "cimplify_pkce";
2309
+ var PKCE_COOKIE_PATH = "/auth";
2310
+ var PKCE_COOKIE_MAX_AGE_SECONDS = 600;
2311
+ function encodePkceState(state) {
2312
+ return encodeURIComponent(JSON.stringify(state));
2313
+ }
2314
+ function decodePkceState(raw) {
2315
+ try {
2316
+ const parsed = JSON.parse(decodeURIComponent(raw));
2317
+ if (typeof parsed?.verifier === "string" && typeof parsed.state === "string" && typeof parsed.returnTo === "string") {
2318
+ return { verifier: parsed.verifier, state: parsed.state, returnTo: parsed.returnTo };
2319
+ }
2320
+ } catch {
2321
+ }
2322
+ return null;
2323
+ }
2324
+
2325
+ // src/internal/discovery.ts
2326
+ var DEFAULT_ISSUER = "https://api.cimplify.io";
2327
+ var DEFAULT_AUTHORIZATION_ENDPOINT = "https://auth.cimplify.io/oauth/authorize";
2328
+ function fallbackAuthorizationEndpoint(issuerBase) {
2329
+ if (issuerBase === DEFAULT_ISSUER) return DEFAULT_AUTHORIZATION_ENDPOINT;
2330
+ throw new Error(
2331
+ `OIDC discovery for "${issuerBase}" is unreachable and no fallback authorize endpoint is known for it. Make discovery reachable (enable CORS) or pass authUrl.`
2332
+ );
2333
+ }
2334
+ var cache = /* @__PURE__ */ new Map();
2335
+ function fetchDiscovery(issuer) {
2336
+ const base = issuer.replace(/\/$/, "");
2337
+ let pending = cache.get(base);
2338
+ if (!pending) {
2339
+ pending = fetch(`${base}/.well-known/openid-configuration`).then((res) => {
2340
+ if (!res.ok) throw new Error(`oidc discovery failed: ${res.status}`);
2341
+ return res.json();
2342
+ });
2343
+ pending.catch(() => cache.delete(base));
2344
+ cache.set(base, pending);
2345
+ }
2346
+ return pending;
2347
+ }
2348
+ async function getAuthorizationEndpoint(issuer) {
2349
+ const base = issuer.replace(/\/$/, "");
2350
+ try {
2351
+ const doc = await fetchDiscovery(base);
2352
+ if (doc.authorization_endpoint) return doc.authorization_endpoint;
2353
+ } catch {
2354
+ }
2355
+ return fallbackAuthorizationEndpoint(base);
2356
+ }
2357
+
2358
+ // src/internal/modal-iframe.ts
2359
+ function openModalIframe(opts) {
2360
+ const overlay = document.createElement("div");
2361
+ overlay.dataset.cimplifyModal = "1";
2362
+ Object.assign(overlay.style, {
2363
+ position: "fixed",
2364
+ inset: "0",
2365
+ background: "rgba(15, 18, 24, 0.55)",
2366
+ zIndex: "2147483647",
2367
+ display: "grid",
2368
+ placeItems: "center",
2369
+ backdropFilter: "blur(2px)"
2370
+ });
2371
+ const card = document.createElement("div");
2372
+ Object.assign(card.style, {
2373
+ width: `${opts.width ?? 480}px`,
2374
+ maxWidth: "calc(100vw - 24px)",
2375
+ height: `${opts.height ?? 720}px`,
2376
+ maxHeight: "calc(100vh - 32px)"
2377
+ });
2378
+ const iframe = document.createElement("iframe");
2379
+ iframe.src = opts.src;
2380
+ iframe.style.width = "100%";
2381
+ iframe.style.height = "100%";
2382
+ iframe.style.border = "none";
2383
+ iframe.style.background = "transparent";
2384
+ iframe.setAttribute(
2385
+ "sandbox",
2386
+ opts.sandbox ?? "allow-scripts allow-same-origin allow-forms allow-popups"
2387
+ );
2388
+ iframe.setAttribute("allow", "publickey-credentials-get; publickey-credentials-create");
2389
+ card.appendChild(iframe);
2390
+ overlay.appendChild(card);
2391
+ document.body.appendChild(overlay);
2392
+ const close = () => {
2393
+ overlay.remove();
2394
+ document.removeEventListener("keydown", onKey);
2395
+ opts.onClose?.();
2396
+ };
2397
+ const onKey = (e) => {
2398
+ if (e.key === "Escape") close();
2399
+ };
2400
+ overlay.addEventListener("click", (e) => {
2401
+ if (e.target === overlay) close();
2402
+ });
2403
+ document.addEventListener("keydown", onKey);
2404
+ return { iframe, close };
2405
+ }
2406
+
2407
+ // src/sign-in.ts
2408
+ var DEFAULT_SCOPE = "openid email phone profile";
2409
+ function resolveAuthorizeEndpoint(opts) {
2410
+ if (opts.authUrl) {
2411
+ return Promise.resolve(`${opts.authUrl.replace(/\/$/, "")}/oauth/authorize`);
2412
+ }
2413
+ return getAuthorizationEndpoint(opts.issuer ?? DEFAULT_ISSUER);
2414
+ }
2415
+ async function startSignIn(opts) {
2416
+ const callbackUri = opts.callbackUri ?? "/auth/callback";
2417
+ const pkce = await generatePkce();
2418
+ const state = generateState();
2419
+ const authorizeEndpoint = await resolveAuthorizeEndpoint(opts);
2420
+ if ((opts.mode ?? "redirect") === "redirect") {
2421
+ startRedirectSignIn(opts, authorizeEndpoint, pkce, state);
2422
+ return;
2423
+ }
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
2433
+ });
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
+ const expectedOrigin = new URL(authorizeEndpoint).origin;
2438
+ const modal = openModalIframe({
2439
+ src,
2440
+ onClose: () => {
2441
+ window.removeEventListener("message", handler);
2442
+ }
2443
+ });
2444
+ const handler = async (event) => {
2445
+ if (event.origin !== expectedOrigin) return;
2446
+ const data = event.data;
2447
+ if (!data || typeof data !== "object" || data.type !== "authorization_response") return;
2448
+ const response = data.response;
2449
+ if (response.error) {
2450
+ modal.close();
2451
+ opts.onError?.({ error: response.error, description: response.error_description });
2452
+ return;
2453
+ }
2454
+ if (!response.code) return;
2455
+ if (response.state !== state) {
2456
+ modal.close();
2457
+ opts.onError?.({ error: "state_mismatch" });
2458
+ return;
2459
+ }
2460
+ 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(() => ({}));
2474
+ modal.close();
2475
+ opts.onSuccess?.({
2476
+ accessToken: payload.accessToken ?? payload.access_token,
2477
+ expiresIn: payload.expiresIn ?? payload.expires_in,
2478
+ scope: payload.scope
2479
+ });
2480
+ } catch (e) {
2481
+ opts.onError?.({ error: "callback_exception", description: String(e) });
2482
+ modal.close();
2483
+ }
2484
+ };
2485
+ window.addEventListener("message", handler);
2486
+ }
2487
+ function startRedirectSignIn(opts, authorizeEndpoint, pkce, state) {
2488
+ const returnTo = opts.returnTo ?? window.location.pathname + window.location.search;
2489
+ const cookieValue = encodePkceState({ verifier: pkce.verifier, state, returnTo });
2490
+ const secure = window.location.protocol === "https:" ? "; Secure" : "";
2491
+ 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()}`);
2505
+ }
2506
+
2276
2507
  // src/elements.ts
2277
2508
  function toCheckoutError(code, message, recoverable) {
2278
2509
  const hint = chunkXA3ZNR75_js.getErrorHint(code);
@@ -2294,6 +2525,27 @@ function generateNonce() {
2294
2525
  }
2295
2526
  return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
2296
2527
  }
2528
+ function readPublicEnv(name) {
2529
+ try {
2530
+ const processLike = globalThis.process;
2531
+ const value = processLike?.env?.[name];
2532
+ return value && value.trim() ? value : void 0;
2533
+ } catch {
2534
+ return void 0;
2535
+ }
2536
+ }
2537
+ function decodeJwtSub(token) {
2538
+ const [, payload] = token.split(".");
2539
+ if (!payload || typeof atob === "undefined") return "";
2540
+ try {
2541
+ const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
2542
+ const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
2543
+ const parsed = JSON.parse(atob(padded));
2544
+ return typeof parsed.sub === "string" ? parsed.sub : "";
2545
+ } catch {
2546
+ return "";
2547
+ }
2548
+ }
2297
2549
  function isAllowedOrigin(origin) {
2298
2550
  try {
2299
2551
  const url = new URL(origin);
@@ -2309,7 +2561,21 @@ function isAllowedOrigin(origin) {
2309
2561
  return false;
2310
2562
  }
2311
2563
  }
2312
- var KNOWN_IFRAME_TYPES = new Set(Object.values(MESSAGE_TYPES));
2564
+ var KNOWN_IFRAME_TYPES = /* @__PURE__ */ new Set([
2565
+ MESSAGE_TYPES.READY,
2566
+ MESSAGE_TYPES.HEIGHT_CHANGE,
2567
+ MESSAGE_TYPES.AUTH_REQUESTED,
2568
+ MESSAGE_TYPES.ERROR,
2569
+ MESSAGE_TYPES.ADDRESS_CHANGED,
2570
+ MESSAGE_TYPES.ADDRESS_SELECTED,
2571
+ MESSAGE_TYPES.PAYMENT_METHOD_SELECTED,
2572
+ MESSAGE_TYPES.CONTACT_PROVIDED,
2573
+ MESSAGE_TYPES.LOGOUT_COMPLETE,
2574
+ MESSAGE_TYPES.CHECKOUT_STATUS,
2575
+ MESSAGE_TYPES.CHECKOUT_COMPLETE,
2576
+ MESSAGE_TYPES.ORDER_TYPE_CHANGED,
2577
+ MESSAGE_TYPES.REQUEST_SUBMIT
2578
+ ]);
2313
2579
  function parseIframeMessage(data) {
2314
2580
  if (!data || typeof data !== "object") {
2315
2581
  return null;
@@ -2319,11 +2585,7 @@ function parseIframeMessage(data) {
2319
2585
  return null;
2320
2586
  }
2321
2587
  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;
2588
+ case MESSAGE_TYPES.AUTH_REQUESTED:
2327
2589
  break;
2328
2590
  case MESSAGE_TYPES.ADDRESS_CHANGED:
2329
2591
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -2341,13 +2603,13 @@ function parseIframeMessage(data) {
2341
2603
  case MESSAGE_TYPES.CHECKOUT_COMPLETE:
2342
2604
  if (typeof record.success !== "boolean") return null;
2343
2605
  break;
2606
+ case MESSAGE_TYPES.CHECKOUT_STATUS:
2607
+ if (typeof record.status !== "string" || !record.context || typeof record.context !== "object") return null;
2608
+ break;
2344
2609
  case MESSAGE_TYPES.READY:
2345
2610
  case MESSAGE_TYPES.HEIGHT_CHANGE:
2346
2611
  if (typeof record.height !== "number") return null;
2347
2612
  break;
2348
- case MESSAGE_TYPES.REQUIRES_OTP:
2349
- if (typeof record.contactMasked !== "string") return null;
2350
- break;
2351
2613
  case MESSAGE_TYPES.ORDER_TYPE_CHANGED:
2352
2614
  if (typeof record.orderType !== "string") return null;
2353
2615
  break;
@@ -2364,6 +2626,7 @@ var CimplifyElements = class {
2364
2626
  this.addressData = null;
2365
2627
  this.paymentData = null;
2366
2628
  this.checkoutInProgress = false;
2629
+ this.authInProgress = false;
2367
2630
  this.activeCheckoutAbort = null;
2368
2631
  this.businessIdResolvePromise = null;
2369
2632
  this.client = client;
@@ -2522,7 +2785,6 @@ var CimplifyElements = class {
2522
2785
  customer_id: this.customerId ?? void 0
2523
2786
  };
2524
2787
  const timeoutMs = options.timeout_ms ?? 18e4;
2525
- const paymentWindow = checkoutElement.getContentWindow();
2526
2788
  return new Promise((resolve) => {
2527
2789
  let settled = false;
2528
2790
  const cleanup = () => {
@@ -2558,18 +2820,7 @@ var CimplifyElements = class {
2558
2820
  if (!message) {
2559
2821
  return;
2560
2822
  }
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) {
2823
+ if (!checkoutElement._acceptsMessageEvent(event, message)) {
2573
2824
  return;
2574
2825
  }
2575
2826
  if (message.type === MESSAGE_TYPES.CHECKOUT_STATUS) {
@@ -2585,6 +2836,16 @@ var CimplifyElements = class {
2585
2836
  enrolled_in_link: message.enrolled_in_link
2586
2837
  });
2587
2838
  }
2839
+ if (message.type === MESSAGE_TYPES.LOGOUT_COMPLETE) {
2840
+ checkoutElement.sendMessage({ type: MESSAGE_TYPES.ABORT_CHECKOUT });
2841
+ settle(
2842
+ toCheckoutError(
2843
+ "AUTH_LOST",
2844
+ "Authentication was cleared during checkout.",
2845
+ true
2846
+ )
2847
+ );
2848
+ }
2588
2849
  };
2589
2850
  if (typeof window !== "undefined") {
2590
2851
  window.addEventListener("message", handleCheckoutMessage);
@@ -2644,12 +2905,7 @@ var CimplifyElements = class {
2644
2905
  return this.options.appearance;
2645
2906
  }
2646
2907
  async hydrateCustomerData() {
2647
- if (!this.accessToken || this.customerData) {
2648
- return;
2649
- }
2650
- if (!this.client.getAccessToken()) {
2651
- this.client.setAccessToken(this.accessToken);
2652
- }
2908
+ if (!this.accessToken || this.customerData) return;
2653
2909
  const linkDataResult = await this.client.link.getLinkData();
2654
2910
  if (!linkDataResult.ok || !linkDataResult.value?.customer) {
2655
2911
  return;
@@ -2660,6 +2916,81 @@ var CimplifyElements = class {
2660
2916
  email: customer.email || null,
2661
2917
  phone: customer.phone || null
2662
2918
  };
2919
+ this.customerId = customer.id;
2920
+ }
2921
+ sourceElementFor(event, message) {
2922
+ for (const element of this.elements.values()) {
2923
+ if (element._acceptsMessageEvent(event, message)) {
2924
+ return element;
2925
+ }
2926
+ }
2927
+ return null;
2928
+ }
2929
+ async applyAccessToken(token) {
2930
+ this.accessToken = token;
2931
+ this.accountId = decodeJwtSub(token);
2932
+ this.client.setAccessToken(token);
2933
+ await this.hydrateCustomerData();
2934
+ return {
2935
+ accountId: this.accountId ?? "",
2936
+ customerId: this.customerId ?? "",
2937
+ token,
2938
+ customer: this.customerData ?? { name: "", email: null, phone: null }
2939
+ };
2940
+ }
2941
+ broadcastAccessToken(token) {
2942
+ this.elements.forEach((element) => {
2943
+ element.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
2944
+ });
2945
+ }
2946
+ startEmbeddedAuth(sourceElement) {
2947
+ if (this.authInProgress) return;
2948
+ const auth = this.options.auth ?? {};
2949
+ const clientId = auth.clientId ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_CLIENT_ID");
2950
+ const redirectUri = auth.redirectUri ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_REDIRECT_URI");
2951
+ if (!clientId || !redirectUri) {
2952
+ sourceElement._emitError({
2953
+ code: "AUTH_CONFIG_REQUIRED",
2954
+ message: "Cimplify OAuth clientId and redirectUri are required."
2955
+ });
2956
+ return;
2957
+ }
2958
+ this.authInProgress = true;
2959
+ void startSignIn({
2960
+ clientId,
2961
+ redirectUri,
2962
+ callbackUri: auth.callbackUri,
2963
+ scope: auth.scope,
2964
+ issuer: auth.issuer,
2965
+ authUrl: auth.authUrl,
2966
+ mode: "modal",
2967
+ onSuccess: async ({ accessToken }) => {
2968
+ this.authInProgress = false;
2969
+ if (!accessToken) {
2970
+ sourceElement._emitError({
2971
+ code: "AUTH_CALLBACK_MISSING_TOKEN",
2972
+ message: "Sign-in callback did not return an access token."
2973
+ });
2974
+ return;
2975
+ }
2976
+ const data = await this.applyAccessToken(accessToken);
2977
+ this.broadcastAccessToken(accessToken);
2978
+ sourceElement._emitAuthenticated(data);
2979
+ },
2980
+ onError: (err2) => {
2981
+ this.authInProgress = false;
2982
+ sourceElement._emitError({
2983
+ code: err2.error,
2984
+ message: err2.description ?? err2.error
2985
+ });
2986
+ }
2987
+ }).catch((error) => {
2988
+ this.authInProgress = false;
2989
+ sourceElement._emitError({
2990
+ code: "AUTH_START_FAILED",
2991
+ message: error instanceof Error ? error.message : "Unable to start sign-in."
2992
+ });
2993
+ });
2663
2994
  }
2664
2995
  handleMessage(event) {
2665
2996
  if (!isAllowedOrigin(event.origin)) {
@@ -2667,26 +2998,11 @@ var CimplifyElements = class {
2667
2998
  }
2668
2999
  const message = parseIframeMessage(event.data);
2669
3000
  if (!message) return;
3001
+ const sourceElement = this.sourceElementFor(event, message);
3002
+ if (!sourceElement) return;
2670
3003
  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;
3004
+ case MESSAGE_TYPES.AUTH_REQUESTED:
3005
+ this.startEmbeddedAuth(sourceElement);
2690
3006
  break;
2691
3007
  case MESSAGE_TYPES.ADDRESS_CHANGED:
2692
3008
  case MESSAGE_TYPES.ADDRESS_SELECTED:
@@ -2856,6 +3172,17 @@ var CimplifyElement = class {
2856
3172
  isMounted() {
2857
3173
  return this.mounted && Boolean(this.iframe) && this.iframe?.isConnected === true;
2858
3174
  }
3175
+ _acceptsMessageEvent(event, message) {
3176
+ const iframeWindow = this.iframe?.contentWindow;
3177
+ if (!iframeWindow || event.source !== iframeWindow) return false;
3178
+ return message.nonce === this.nonce;
3179
+ }
3180
+ _emitAuthenticated(data) {
3181
+ this.emit(EVENT_TYPES.AUTHENTICATED, data);
3182
+ }
3183
+ _emitError(error) {
3184
+ this.emit(EVENT_TYPES.ERROR, error);
3185
+ }
2859
3186
  async createIframe() {
2860
3187
  if (!this.container) return;
2861
3188
  const resolvedBusinessId = this.businessId ?? await this.parent.resolveBusinessId();
@@ -2899,17 +3226,9 @@ var CimplifyElement = class {
2899
3226
  if (!isAllowedOrigin(event.origin)) {
2900
3227
  return;
2901
3228
  }
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
3229
  const message = parseIframeMessage(event.data);
2912
3230
  if (!message) return;
3231
+ if (!this._acceptsMessageEvent(event, message)) return;
2913
3232
  switch (message.type) {
2914
3233
  case MESSAGE_TYPES.READY:
2915
3234
  this.ready = true;
@@ -2928,7 +3247,7 @@ var CimplifyElement = class {
2928
3247
  submitLabel: this.options.submitLabel
2929
3248
  });
2930
3249
  const token = this.parent.getAccessToken();
2931
- if (token && this.type !== ELEMENT_TYPES.AUTH) {
3250
+ if (token) {
2932
3251
  this.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
2933
3252
  }
2934
3253
  this.pendingInit = null;
@@ -2939,22 +3258,6 @@ var CimplifyElement = class {
2939
3258
  case MESSAGE_TYPES.HEIGHT_CHANGE:
2940
3259
  if (this.iframe) this.iframe.style.height = `${message.height}px`;
2941
3260
  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
3261
  case MESSAGE_TYPES.ERROR:
2959
3262
  this.emit(EVENT_TYPES.ERROR, { code: message.code, message: message.message });
2960
3263
  break;
@@ -3010,6 +3313,7 @@ exports.CimplifyElement = CimplifyElement;
3010
3313
  exports.CimplifyElements = CimplifyElements;
3011
3314
  exports.DEFAULT_COUNTRY = DEFAULT_COUNTRY;
3012
3315
  exports.DEFAULT_CURRENCY = DEFAULT_CURRENCY;
3316
+ exports.DEFAULT_ISSUER = DEFAULT_ISSUER;
3013
3317
  exports.DEVICE_TYPE = DEVICE_TYPE;
3014
3318
  exports.ELEMENT_TYPES = ELEMENT_TYPES;
3015
3319
  exports.EVENT_TYPES = EVENT_TYPES;
@@ -3028,14 +3332,20 @@ exports.PAYMENT_METHOD = PAYMENT_METHOD;
3028
3332
  exports.PAYMENT_MUTATION = PAYMENT_MUTATION;
3029
3333
  exports.PAYMENT_STATE = PAYMENT_STATE;
3030
3334
  exports.PICKUP_TIME_TYPE = PICKUP_TIME_TYPE;
3335
+ exports.PKCE_COOKIE = PKCE_COOKIE;
3336
+ exports.PKCE_COOKIE_PATH = PKCE_COOKIE_PATH;
3031
3337
  exports.SchedulingService = SchedulingService;
3032
3338
  exports.combine = combine;
3033
3339
  exports.combineObject = combineObject;
3034
3340
  exports.createElements = createElements;
3341
+ exports.decodePkceState = decodePkceState;
3035
3342
  exports.err = err;
3036
3343
  exports.flatMap = flatMap;
3037
3344
  exports.fromPromise = fromPromise;
3038
3345
  exports.generateIdempotencyKey = generateIdempotencyKey;
3346
+ exports.generatePkce = generatePkce;
3347
+ exports.generateState = generateState;
3348
+ exports.getAuthorizationEndpoint = getAuthorizationEndpoint;
3039
3349
  exports.getOrElse = getOrElse;
3040
3350
  exports.isErr = isErr;
3041
3351
  exports.isOk = isOk;
@@ -3043,6 +3353,7 @@ exports.mapError = mapError;
3043
3353
  exports.mapResult = mapResult;
3044
3354
  exports.ok = ok;
3045
3355
  exports.safe = safe;
3356
+ exports.startSignIn = startSignIn;
3046
3357
  exports.toNullable = toNullable;
3047
3358
  exports.tryCatch = tryCatch;
3048
3359
  exports.unwrap = unwrap;