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