@dintero/checkout-web-sdk 0.12.15 → 0.12.16

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.
@@ -6,7 +6,7 @@ require('native-promise-only');
6
6
 
7
7
  var pkg = {
8
8
  name: "@dintero/checkout-web-sdk",
9
- version: "0.12.15",
9
+ version: "0.12.16",
10
10
  description: "Dintero Checkout SDK for web frontends",
11
11
  main: "dist/dintero-checkout-web-sdk.cjs.js",
12
12
  module: "dist/dintero-checkout-web-sdk.esm.js",
@@ -40,11 +40,11 @@ var pkg = {
40
40
  devDependencies: {
41
41
  "@babel/core": "7.29.7",
42
42
  "@babel/preset-typescript": "7.29.7",
43
- "@biomejs/biome": "2.4.15",
43
+ "@biomejs/biome": "2.5.0",
44
44
  "@preconstruct/cli": "2.8.13",
45
45
  "@semantic-release/exec": "7.1.0",
46
46
  "@semantic-release/git": "10.0.1",
47
- "@vitest/browser": "4.1.7",
47
+ "@vitest/browser": "4.1.8",
48
48
  "@vitest/browser-webdriverio": "^4.0.4",
49
49
  "semantic-release": "25.0.3",
50
50
  typescript: "6.0.3",
@@ -224,6 +224,19 @@ const getPopOutUrl = ({
224
224
  }
225
225
  return `${padTrailingSlash(endpoint)}?${params.toString()}`;
226
226
  };
227
+
228
+ /**
229
+ * Get the target origin for postMessage calls derived from the endpoint.
230
+ * Falls back to the default checkout endpoint when none is configured.
231
+ */
232
+ const getTargetOrigin = endpoint => {
233
+ const resolvedEndpoint = endpoint || "https://checkout.dintero.com";
234
+ try {
235
+ return new URL(resolvedEndpoint).origin;
236
+ } catch {
237
+ throw new Error("Invalid endpoint");
238
+ }
239
+ };
227
240
  const getHostname = () => {
228
241
  try {
229
242
  const {
@@ -249,6 +262,7 @@ const hostnameIsTop = () => {
249
262
  const url = {
250
263
  getPopOutUrl,
251
264
  getSessionUrl,
265
+ getTargetOrigin,
252
266
  windowLocationAssign
253
267
  };
254
268
 
@@ -352,38 +366,38 @@ const openPopOut = async options => {
352
366
  popOutWindow
353
367
  };
354
368
  };
355
- const postPopOutSessionLock = (popOutWindow, sid) => {
369
+ const postPopOutSessionLock = (popOutWindow, sid, targetOrigin) => {
356
370
  try {
357
371
  if (popOutWindow) {
358
372
  popOutWindow.postMessage({
359
373
  type: "LockSession",
360
374
  sid
361
- }, "*");
375
+ }, targetOrigin);
362
376
  }
363
377
  } catch (e) {
364
378
  console.error(e);
365
379
  }
366
380
  };
367
- const postPopOutSessionRefresh = (popOutWindow, sid) => {
381
+ const postPopOutSessionRefresh = (popOutWindow, sid, targetOrigin) => {
368
382
  try {
369
383
  if (popOutWindow) {
370
384
  popOutWindow.postMessage({
371
385
  type: "RefreshSession",
372
386
  sid
373
- }, "*");
387
+ }, targetOrigin);
374
388
  }
375
389
  } catch (e) {
376
390
  console.error(e);
377
391
  }
378
392
  };
379
- const postPopOutActivePaymentProductType = (popOutWindow, sid, paymentProductType) => {
393
+ const postPopOutActivePaymentProductType = (popOutWindow, sid, targetOrigin, paymentProductType) => {
380
394
  try {
381
395
  if (popOutWindow) {
382
396
  popOutWindow.postMessage({
383
397
  type: "SetActivePaymentProductType",
384
398
  sid,
385
399
  payment_product_type: paymentProductType
386
- }, "*");
400
+ }, targetOrigin);
387
401
  }
388
402
  } catch (e) {
389
403
  console.error(e);
@@ -840,135 +854,135 @@ const removePopOutButton = () => {
840
854
  /**
841
855
  * Post a message acknowledgement to the checkout iframe.
842
856
  */
843
- const postAck = (source, event) => {
857
+ const postAck = (source, event, targetOrigin) => {
844
858
  if (event.data.mid && source) {
845
859
  source.postMessage({
846
860
  ack: event.data.mid
847
- }, event.origin || "*");
861
+ }, targetOrigin);
848
862
  }
849
863
  };
850
864
 
851
865
  /**
852
866
  * Post a SessionLock-event to the checkout iframe.
853
867
  */
854
- const postSessionLock = (iframe, sid) => {
868
+ const postSessionLock = (iframe, sid, targetOrigin) => {
855
869
  if (iframe.contentWindow) {
856
870
  iframe.contentWindow.postMessage({
857
871
  type: "LockSession",
858
872
  sid
859
- }, "*");
873
+ }, targetOrigin);
860
874
  }
861
875
  };
862
876
 
863
877
  /**
864
878
  * Post the validation result to the checkout iframe
865
879
  */
866
- const postValidationResult = (iframe, sid, result) => {
880
+ const postValidationResult = (iframe, sid, result, targetOrigin) => {
867
881
  if (iframe.contentWindow) {
868
882
  iframe.contentWindow.postMessage({
869
883
  type: "ValidationResult",
870
884
  sid,
871
885
  ...result
872
- }, "*");
886
+ }, targetOrigin);
873
887
  }
874
888
  };
875
889
 
876
890
  /**
877
891
  * Post the address call back result to the checkout iframe
878
892
  */
879
- const postAddressCallbackResult = (iframe, sid, result) => {
893
+ const postAddressCallbackResult = (iframe, sid, result, targetOrigin) => {
880
894
  if (iframe.contentWindow) {
881
895
  iframe.contentWindow.postMessage({
882
896
  type: "AddressCallbackResult",
883
897
  sid,
884
898
  ...result
885
- }, "*");
899
+ }, targetOrigin);
886
900
  }
887
901
  };
888
902
 
889
903
  /**
890
904
  * Post RefreshSession-event to the checkout iframe.
891
905
  */
892
- const postSessionRefresh = (iframe, sid) => {
906
+ const postSessionRefresh = (iframe, sid, targetOrigin) => {
893
907
  if (iframe.contentWindow) {
894
908
  iframe.contentWindow.postMessage({
895
909
  type: "RefreshSession",
896
910
  sid
897
- }, "*");
911
+ }, targetOrigin);
898
912
  }
899
913
  };
900
914
 
901
915
  /**
902
916
  * Post SetActivePaymentProductType-event to the checkout iframe.
903
917
  */
904
- const postActivePaymentProductType = (iframe, sid, paymentProductType) => {
918
+ const postActivePaymentProductType = (iframe, sid, targetOrigin, paymentProductType) => {
905
919
  if (iframe.contentWindow) {
906
920
  iframe.contentWindow.postMessage({
907
921
  type: "SetActivePaymentProductType",
908
922
  sid,
909
923
  payment_product_type: paymentProductType
910
- }, "*");
924
+ }, targetOrigin);
911
925
  }
912
926
  };
913
927
 
914
928
  /**
915
929
  * Post ClosePopOut-event to the checkout iframe.
916
930
  */
917
- const postValidatePopOutEvent = (iframe, sid) => {
931
+ const postValidatePopOutEvent = (iframe, sid, targetOrigin) => {
918
932
  if (iframe.contentWindow) {
919
933
  iframe.contentWindow.postMessage({
920
934
  type: "ValidatingPopOut",
921
935
  sid
922
- }, "*");
936
+ }, targetOrigin);
923
937
  }
924
938
  };
925
939
 
926
940
  /**
927
941
  * Post OpenPopOutFailed-event to the checkout iframe.
928
942
  */
929
- const postOpenPopOutFailedEvent = (iframe, sid) => {
943
+ const postOpenPopOutFailedEvent = (iframe, sid, targetOrigin) => {
930
944
  if (iframe.contentWindow) {
931
945
  iframe.contentWindow.postMessage({
932
946
  type: "OpenPopOutFailed",
933
947
  sid
934
- }, "*");
948
+ }, targetOrigin);
935
949
  }
936
950
  };
937
951
 
938
952
  /**
939
953
  * Post OpenedPopOut-event to the checkout iframe.
940
954
  */
941
- const postOpenPopOutEvent = (iframe, sid) => {
955
+ const postOpenPopOutEvent = (iframe, sid, targetOrigin) => {
942
956
  if (iframe.contentWindow) {
943
957
  iframe.contentWindow.postMessage({
944
958
  type: "OpenedPopOut",
945
959
  sid
946
- }, "*");
960
+ }, targetOrigin);
947
961
  }
948
962
  };
949
963
 
950
964
  /**
951
965
  * Post ClosePopOut-event to the checkout iframe.
952
966
  */
953
- const postClosePopOutEvent = (iframe, sid) => {
967
+ const postClosePopOutEvent = (iframe, sid, targetOrigin) => {
954
968
  if (iframe.contentWindow) {
955
969
  iframe.contentWindow.postMessage({
956
970
  type: "ClosedPopOut",
957
971
  sid
958
- }, "*");
972
+ }, targetOrigin);
959
973
  }
960
974
  };
961
975
 
962
976
  /**
963
977
  * Post SetLanguage-event to the checkout iframe.
964
978
  */
965
- const postSetLanguage = (iframe, sid, language) => {
979
+ const postSetLanguage = (iframe, sid, language, targetOrigin) => {
966
980
  if (iframe.contentWindow) {
967
981
  iframe.contentWindow.postMessage({
968
982
  type: "SetLanguage",
969
983
  sid,
970
984
  language
971
- }, "*");
985
+ }, targetOrigin);
972
986
  }
973
987
  };
974
988
 
@@ -994,7 +1008,7 @@ const subscribe = options => {
994
1008
  const correctSid = event.data && event.data.sid === sid;
995
1009
  const correctMessageType = eventTypes.indexOf(event.data?.type) !== -1;
996
1010
  if (correctOrigin && correctWindow && correctSid && correctMessageType) {
997
- postAck(checkout.iframe.contentWindow, event);
1011
+ postAck(checkout.iframe.contentWindow, event, endpointUrl.origin);
998
1012
  handler(event.data, checkout);
999
1013
  }
1000
1014
  };
@@ -1079,7 +1093,7 @@ const createPopOutMessageHandler = (source, checkout) => {
1079
1093
  // biome-ignore lint/suspicious/noExplicitAny: internal LanguageChanged event, not part of SessionEvent
1080
1094
  handler: (eventData, checkout) => {
1081
1095
  // Tell the embedded checkout to change language.
1082
- postSetLanguage(checkout.iframe, checkout.options.sid, eventData.language);
1096
+ postSetLanguage(checkout.iframe, checkout.options.sid, eventData.language, url.getTargetOrigin(checkout.options.endpoint));
1083
1097
  }
1084
1098
  };
1085
1099
 
@@ -1151,7 +1165,7 @@ const showPopOut = async (event, checkout) => {
1151
1165
  onOpen: popOutWindow => createPopOutMessageHandler(popOutWindow, checkout),
1152
1166
  onClose: () => {
1153
1167
  removeBackdrop();
1154
- postClosePopOutEvent(checkout.iframe, checkout.options.sid);
1168
+ postClosePopOutEvent(checkout.iframe, checkout.options.sid, url.getTargetOrigin(checkout.options.endpoint));
1155
1169
  setPopOutButtonDisabled(false);
1156
1170
  checkout.popOutWindow = undefined;
1157
1171
  }
@@ -1162,7 +1176,7 @@ const showPopOut = async (event, checkout) => {
1162
1176
  popOutWindow
1163
1177
  } = openPopOutResult;
1164
1178
  if (popOutWindow) {
1165
- postOpenPopOutEvent(checkout.iframe, checkout.options.sid);
1179
+ postOpenPopOutEvent(checkout.iframe, checkout.options.sid, url.getTargetOrigin(checkout.options.endpoint));
1166
1180
  // Add pop out window to checkout instance
1167
1181
  checkout.popOutWindow = popOutWindow;
1168
1182
  createBackdrop({
@@ -1172,7 +1186,7 @@ const showPopOut = async (event, checkout) => {
1172
1186
  });
1173
1187
  return true;
1174
1188
  } else {
1175
- postOpenPopOutFailedEvent(checkout.iframe, checkout.options.sid);
1189
+ postOpenPopOutFailedEvent(checkout.iframe, checkout.options.sid, url.getTargetOrigin(checkout.options.endpoint));
1176
1190
  return false;
1177
1191
  }
1178
1192
  };
@@ -1186,7 +1200,7 @@ const createPopOutValidationCallback = (event, checkout) => {
1186
1200
  return result => {
1187
1201
  // Tell the embedded iframe about the validation result so it can show an error message if
1188
1202
  // the validation failed.
1189
- postValidationResult(checkout.iframe, checkout.options.sid, result);
1203
+ postValidationResult(checkout.iframe, checkout.options.sid, result, url.getTargetOrigin(checkout.options.endpoint));
1190
1204
  if (result.success && checkout.popOutWindow) {
1191
1205
  // Redirect user to session in pop out window
1192
1206
  checkout.popOutWindow.location.href = url.getPopOutUrl({
@@ -1217,7 +1231,7 @@ const handlePopOutButtonClick = async (event, checkout) => {
1217
1231
  // Let the host application validate the payment session before opening checkout.
1218
1232
 
1219
1233
  // Tell the embedded iframe that we are validating the session
1220
- postValidatePopOutEvent(checkout.iframe, checkout.options.sid);
1234
+ postValidatePopOutEvent(checkout.iframe, checkout.options.sid, url.getTargetOrigin(checkout.options.endpoint));
1221
1235
 
1222
1236
  // Create callback function added to the SDK event and onValidateSession attributes
1223
1237
  const callback = createPopOutValidationCallback(event, checkout);
@@ -1236,7 +1250,7 @@ const handlePopOutButtonClick = async (event, checkout) => {
1236
1250
  postValidationResult(checkout.iframe, checkout.options.sid, {
1237
1251
  success: false,
1238
1252
  clientValidationError: "Validation runtime error"
1239
- });
1253
+ }, url.getTargetOrigin(checkout.options.endpoint));
1240
1254
  }
1241
1255
  }
1242
1256
  };
@@ -1331,6 +1345,10 @@ const embed = async options => {
1331
1345
  onAddressCallback,
1332
1346
  popOut
1333
1347
  } = internalOptions;
1348
+
1349
+ // Origin of the checkout endpoint, used as the target origin for all
1350
+ // postMessage calls so messages are only ever delivered to the trusted origin.
1351
+ const targetOrigin = url.getTargetOrigin(endpoint);
1334
1352
  let checkout;
1335
1353
  const subscriptions = [];
1336
1354
  let has_delivered_final_event = false;
@@ -1420,30 +1438,30 @@ const embed = async options => {
1420
1438
  };
1421
1439
  const lockSession = () => {
1422
1440
  return promisifyAction(() => {
1423
- postSessionLock(iframe, sid);
1424
- popOutModule.postPopOutSessionLock(checkout?.popOutWindow, sid);
1441
+ postSessionLock(iframe, sid, targetOrigin);
1442
+ popOutModule.postPopOutSessionLock(checkout?.popOutWindow, sid, targetOrigin);
1425
1443
  }, CheckoutEvents.SessionLocked, CheckoutEvents.SessionLockFailed);
1426
1444
  };
1427
1445
  const refreshSession = () => {
1428
1446
  return promisifyAction(() => {
1429
- postSessionRefresh(iframe, sid);
1430
- popOutModule.postPopOutSessionRefresh(checkout?.popOutWindow, sid);
1447
+ postSessionRefresh(iframe, sid, targetOrigin);
1448
+ popOutModule.postPopOutSessionRefresh(checkout?.popOutWindow, sid, targetOrigin);
1431
1449
  }, CheckoutEvents.SessionUpdated, CheckoutEvents.SessionNotFound);
1432
1450
  };
1433
1451
  const setActivePaymentProductType = paymentProductType => {
1434
1452
  // Send to either embed or pop out
1435
1453
  if (options.popOut) {
1436
- popOutModule.postPopOutActivePaymentProductType(checkout?.popOutWindow, sid, paymentProductType);
1454
+ popOutModule.postPopOutActivePaymentProductType(checkout?.popOutWindow, sid, targetOrigin, paymentProductType);
1437
1455
  } else {
1438
- postActivePaymentProductType(iframe, sid, paymentProductType);
1456
+ postActivePaymentProductType(iframe, sid, targetOrigin, paymentProductType);
1439
1457
  }
1440
1458
  };
1441
1459
  const submitValidationResult = result => {
1442
- postValidationResult(iframe, sid, result);
1460
+ postValidationResult(iframe, sid, result, targetOrigin);
1443
1461
  // For pop out we do validation when opening the pop out
1444
1462
  };
1445
1463
  const submitAddressCallbackResult = result => {
1446
- postAddressCallbackResult(iframe, sid, result);
1464
+ postAddressCallbackResult(iframe, sid, result, targetOrigin);
1447
1465
  // For pop out we do validation when opening the pop out
1448
1466
  };
1449
1467