@loafmarkets/ui 0.1.409 → 0.1.410

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/index.js CHANGED
@@ -2669,6 +2669,22 @@ var PropertyTour = React5__namespace.forwardRef(
2669
2669
  }
2670
2670
  );
2671
2671
  PropertyTour.displayName = "PropertyTour";
2672
+
2673
+ // src/lib/isSafeUrl.ts
2674
+ var CONTROL_CHARS = /[\u0000-\u001F\u007F]/g;
2675
+ function isSafeUrl(url) {
2676
+ if (!url) return false;
2677
+ const cleaned = url.replace(CONTROL_CHARS, "").replace(/\\/g, "/").trim();
2678
+ if (cleaned === "") return false;
2679
+ if (cleaned.startsWith("//")) return false;
2680
+ if (cleaned.startsWith("/")) return true;
2681
+ try {
2682
+ const { protocol } = new URL(cleaned);
2683
+ return protocol === "http:" || protocol === "https:";
2684
+ } catch {
2685
+ return false;
2686
+ }
2687
+ }
2672
2688
  var ITEMS_PER_PAGE = 5;
2673
2689
  var ITEMS_PER_PAGE_MOBILE = 5;
2674
2690
  var ensureAnimationsInjected = () => {
@@ -2864,7 +2880,7 @@ function NewsArticleModal({ item, onClose }) {
2864
2880
  ] }),
2865
2881
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "1px", background: "rgba(255,255,255,0.08)", marginBottom: "1.25rem" } }),
2866
2882
  item.summary ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: "rgba(255,255,255,0.8)", lineHeight: 1.75, margin: 0 }, children: item.summary }) : /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.8rem", color: "rgba(255,255,255,0.35)", fontStyle: "italic", margin: 0 }, children: "Summary not available for this article." }),
2867
- item.url && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: "1.25rem", paddingTop: "1rem", borderTop: "1px solid rgba(255,255,255,0.08)" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2883
+ item.url && isSafeUrl(item.url) && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: "1.25rem", paddingTop: "1rem", borderTop: "1px solid rgba(255,255,255,0.08)" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2868
2884
  "a",
2869
2885
  {
2870
2886
  href: item.url,
@@ -6640,6 +6656,16 @@ var PropertySubheader = React5__namespace.forwardRef(
6640
6656
  }
6641
6657
  );
6642
6658
  PropertySubheader.displayName = "PropertySubheader";
6659
+
6660
+ // src/lib/isTrustedTransakOrigin.ts
6661
+ function isTrustedTransakOrigin(eventOrigin, widgetUrl) {
6662
+ if (!widgetUrl) return false;
6663
+ try {
6664
+ return eventOrigin === new URL(widgetUrl).origin;
6665
+ } catch {
6666
+ return false;
6667
+ }
6668
+ }
6643
6669
  var DEFAULT_LOGO_SRC = Loaf_logo_Banner_default;
6644
6670
  var DEFAULT_LOGO_ALT = "Loaf";
6645
6671
  var OTP_INPUT_LENGTH = 6;
@@ -6780,7 +6806,7 @@ var LoginPopup = ({
6780
6806
  React5.useEffect(() => {
6781
6807
  if (!transakWidgetUrl) return;
6782
6808
  const handleTransakMessage = (event) => {
6783
- if (!event.origin.includes("transak.com") && !event.origin.includes("global.transak.com")) {
6809
+ if (!isTrustedTransakOrigin(event.origin, transakWidgetUrl)) {
6784
6810
  return;
6785
6811
  }
6786
6812
  try {
@@ -12297,7 +12323,7 @@ function PropertyDocuments({ documentsData, highlightDocument, onClearHighlight
12297
12323
  const [previewTitle, setPreviewTitle] = React5.useState(null);
12298
12324
  const backendDocuments = Array.isArray(documentsData?.documents) ? documentsData.documents : [];
12299
12325
  const liveDocs = backendDocuments.filter(
12300
- (d) => Boolean(d.documentUrl) && LIVE_TITLE_PATTERNS.some((rx) => rx.test(d.title))
12326
+ (d) => Boolean(d.documentUrl) && isSafeUrl(d.documentUrl) && LIVE_TITLE_PATTERNS.some((rx) => rx.test(d.title))
12301
12327
  );
12302
12328
  const comingSoonDocs = COMING_SOON_TITLES.filter(
12303
12329
  (title) => !liveDocs.some((d) => d.title.toLowerCase().includes(title.toLowerCase()) || title.toLowerCase().includes(d.title.toLowerCase()))