@shuffleio/shuffle-mcps 0.0.45 → 0.0.46

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.
@@ -2,7 +2,7 @@ import {
2
2
  fetchApps,
3
3
  fetchAppsViaApiConfig,
4
4
  invalidateAppsCache
5
- } from "./chunk-5LZ5IZ2O.mjs";
5
+ } from "./chunk-45B7UK6Q.mjs";
6
6
  export {
7
7
  fetchApps,
8
8
  fetchAppsViaApiConfig,
@@ -1,4 +1,40 @@
1
1
  // fetchBreaker.ts
2
+ var rewriteShufflerApiToShuffleSecurity = (input) => {
3
+ if (typeof window === "undefined") return input;
4
+ const currentHost = window.location.hostname.toLowerCase();
5
+ const isOnShuffleSecurity = currentHost === "shuffle.security" || currentHost.endsWith(".shuffle.security") || currentHost === "localhost" || currentHost === "127.0.0.1" || currentHost.includes("lovable");
6
+ if (!isOnShuffleSecurity) return input;
7
+ let urlStr = null;
8
+ if (typeof input === "string") urlStr = input;
9
+ else if (input instanceof URL) urlStr = input.toString();
10
+ else if (input && typeof input.url === "string") urlStr = input.url;
11
+ if (!urlStr) return input;
12
+ if (!urlStr.includes("/api/") || urlStr.includes("/api/v1/auth/exchange")) {
13
+ return input;
14
+ }
15
+ try {
16
+ const u = new URL(urlStr, window.location.href);
17
+ const host = u.hostname.toLowerCase();
18
+ if (host === "shuffler.io" || host === "www.shuffler.io") {
19
+ u.protocol = "https:";
20
+ u.hostname = "uk.shuffle.security";
21
+ const rewritten = u.toString();
22
+ if (typeof input === "string") return rewritten;
23
+ if (input instanceof URL) return new URL(rewritten);
24
+ if (typeof Request !== "undefined" && input instanceof Request) return new Request(rewritten, input);
25
+ } else if (host.endsWith(".shuffler.io")) {
26
+ const subdomain = host.slice(0, -".shuffler.io".length);
27
+ u.protocol = "https:";
28
+ u.hostname = `${subdomain}.shuffle.security`;
29
+ const rewritten = u.toString();
30
+ if (typeof input === "string") return rewritten;
31
+ if (input instanceof URL) return new URL(rewritten);
32
+ if (typeof Request !== "undefined" && input instanceof Request) return new Request(rewritten, input);
33
+ }
34
+ } catch {
35
+ }
36
+ return input;
37
+ };
2
38
  var FAIL_THRESHOLD = 12;
3
39
  var ROLLING_WINDOW_MS = 5e3;
4
40
  var COOLDOWN_MS = 1e4;
@@ -64,12 +100,24 @@ var withStoredAuth = (input, init) => {
64
100
  if (url.pathname === "/api/v1/login" || url.pathname === "/api/v1/users/register") return init;
65
101
  const sessionToken = window.localStorage.getItem("session_token");
66
102
  const token = sessionToken && sessionToken.trim().length > 0 ? sessionToken.trim() : null;
103
+ const authMode = window.localStorage.getItem("shuffle_auth_mode");
104
+ const isCapacitor = Boolean(
105
+ window.Capacitor?.isNativePlatform?.() || window._isCapacitorNative
106
+ );
67
107
  const requestHeaders = typeof Request !== "undefined" && input instanceof Request ? input.headers : void 0;
68
108
  const headers = new Headers(requestHeaders);
69
109
  if (init?.headers) {
70
110
  new Headers(init.headers).forEach((value, name) => headers.set(name, value));
71
111
  }
72
- if (token && !headers.has("Authorization")) {
112
+ const rootDomain = (host) => {
113
+ const parts = host.split(".");
114
+ return parts.length <= 2 ? host : parts.slice(-2).join(".");
115
+ };
116
+ const backendHost = url.hostname.toLowerCase();
117
+ const frontendHost = window.location.hostname.toLowerCase();
118
+ const isLocalPair = ["localhost", "127.0.0.1"].includes(backendHost) && ["localhost", "127.0.0.1"].includes(frontendHost);
119
+ const isCrossDomain = backendHost !== frontendHost && !isLocalPair && rootDomain(backendHost) !== rootDomain(frontendHost);
120
+ if (token && (authMode === "bearer" || isCapacitor || isCrossDomain) && !headers.has("Authorization")) {
73
121
  headers.set("Authorization", `Bearer ${token}`);
74
122
  }
75
123
  if (!headers.has("Org-Id")) {
@@ -117,9 +165,10 @@ var installFetchBreaker = () => {
117
165
  installed = true;
118
166
  const original = window.fetch.bind(window);
119
167
  window.fetch = (async (input, init) => {
120
- const authenticatedInit = withStoredAuth(input, init);
121
- const key = keyFor(input, authenticatedInit);
122
- if (!key) return original(input, authenticatedInit);
168
+ const finalInput = rewriteShufflerApiToShuffleSecurity(input);
169
+ const authenticatedInit = withStoredAuth(finalInput, init);
170
+ const key = keyFor(finalInput, authenticatedInit);
171
+ if (!key) return original(finalInput, authenticatedInit);
123
172
  const entry = getEntry(key);
124
173
  const now = Date.now();
125
174
  let isProbe = false;
@@ -153,7 +202,7 @@ var installFetchBreaker = () => {
153
202
  };
154
203
  let response;
155
204
  try {
156
- response = await original(input, authenticatedInit);
205
+ response = await original(finalInput, authenticatedInit);
157
206
  } catch (err) {
158
207
  const ts = Date.now();
159
208
  entry.failures.push(ts);
@@ -240,23 +289,26 @@ var getShuffleCoreBaseUrl = () => {
240
289
  if (savedCore && savedCore.trim().length > 0) {
241
290
  return savedCore.trim().replace(/\/+$/, "");
242
291
  }
292
+ } catch {
293
+ }
294
+ }
295
+ if (typeof window !== "undefined" && isManagedDomain()) {
296
+ return "https://shuffler.io";
297
+ }
298
+ if (typeof window !== "undefined") {
299
+ try {
243
300
  const customHost = localStorage.getItem("shuffle_custom_host_url");
244
301
  if (customHost && customHost.trim().length > 0) {
245
302
  const cleaned = customHost.trim().replace(/\/+$/, "");
246
303
  if (cleaned.includes(":5001")) {
247
304
  return cleaned.replace(":5001", ":3001");
248
305
  }
249
- return cleaned;
250
306
  }
251
307
  } catch {
252
308
  }
253
309
  }
254
310
  if (typeof window !== "undefined") {
255
311
  const hostname = window.location.hostname;
256
- const isManaged = isManagedDomain();
257
- if (isManaged) {
258
- return "https://shuffler.io";
259
- }
260
312
  if (window.location.port === "3001") {
261
313
  return window.location.origin;
262
314
  }
@@ -270,6 +322,212 @@ var getShuffleCoreUrl = (path) => {
270
322
  const cleanPath = path.startsWith("/") ? path : `/${path}`;
271
323
  return `${base}${cleanPath}`;
272
324
  };
325
+ var getShuffleSecurityBaseUrl = () => {
326
+ const envUrl = readEnv("VITE_SHUFFLE_SECURITY_URL") || readEnv("SHUFFLE_SECURITY_URL");
327
+ if (envUrl) {
328
+ return envUrl.replace(/\/+$/, "");
329
+ }
330
+ if (typeof window !== "undefined") {
331
+ if (window.location.port !== "3001" && !window.location.hostname.includes("shuffler.io")) {
332
+ return window.location.origin;
333
+ }
334
+ if (window.location.port === "3001") {
335
+ return `${window.location.protocol}//${window.location.hostname}:3002`;
336
+ }
337
+ }
338
+ return "https://shuffle.security";
339
+ };
340
+ var getShuffleSecurityUrl = (path) => {
341
+ const base = getShuffleSecurityBaseUrl();
342
+ if (!path) return base;
343
+ const cleanPath = path.startsWith("/") ? path : `/${path}`;
344
+ return `${base}${cleanPath}`;
345
+ };
346
+ var getCurrentShuffleProduct = (override) => {
347
+ if (override) {
348
+ const o = override.trim().toLowerCase();
349
+ if (o === "core" || o === "automation") return "core";
350
+ if (o === "security") return "security";
351
+ }
352
+ if (typeof window !== "undefined") {
353
+ try {
354
+ const urlParams = new URLSearchParams(window.location.search);
355
+ const param = urlParams.get("product") || urlParams.get("shuffle_product");
356
+ if (param) {
357
+ const p = param.trim().toLowerCase();
358
+ if (p === "core" || p === "automation") return "core";
359
+ if (p === "security") return "security";
360
+ }
361
+ } catch {
362
+ }
363
+ }
364
+ const envProduct = readEnv("VITE_SHUFFLE_PRODUCT") || readEnv("SHUFFLE_PRODUCT");
365
+ if (envProduct) {
366
+ const p = envProduct.trim().toLowerCase();
367
+ if (p === "core" || p === "automation") return "core";
368
+ if (p === "security") return "security";
369
+ }
370
+ if (typeof window !== "undefined") {
371
+ const win = window;
372
+ if (win.__SHUFFLE_PRODUCT__) {
373
+ const p = String(win.__SHUFFLE_PRODUCT__).trim().toLowerCase();
374
+ if (p === "core" || p === "automation") return "core";
375
+ if (p === "security") return "security";
376
+ }
377
+ const hostname = window.location.hostname.toLowerCase();
378
+ const port = window.location.port;
379
+ if (port === "3001") return "core";
380
+ if (port === "3002") return "security";
381
+ if (hostname.includes("shuffler.io")) {
382
+ if (hostname.startsWith("security.") || hostname.includes(".security.")) {
383
+ return "security";
384
+ }
385
+ return "core";
386
+ }
387
+ if (hostname.includes("shuffle.security")) {
388
+ return "security";
389
+ }
390
+ }
391
+ return "security";
392
+ };
393
+ var CORE_EXCLUSIVE_PATH_PREFIXES = [
394
+ "/workflows",
395
+ "/new-dashboard",
396
+ "/apps/new"
397
+ ];
398
+ var CORE_ADMIN_TABS = ["datastore", "files", "locations", "runtime_locations"];
399
+ var SECURITY_EXCLUSIVE_PATH_PREFIXES = [
400
+ "/incidents",
401
+ "/incidents-simple",
402
+ "/alerts",
403
+ "/cases",
404
+ "/monitors",
405
+ "/vulnerabilities",
406
+ "/detection",
407
+ "/assets",
408
+ "/tickets"
409
+ ];
410
+ var isCoreExclusivePath = (path) => {
411
+ if (!path) return false;
412
+ const clean = path.startsWith("/") ? path : `/${path}`;
413
+ const [pathname, search] = clean.split("?");
414
+ if (CORE_EXCLUSIVE_PATH_PREFIXES.some((prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`))) {
415
+ return true;
416
+ }
417
+ if (pathname === "/admin" && search) {
418
+ const params = new URLSearchParams(search);
419
+ const tab = params.get("tab");
420
+ if (tab && CORE_ADMIN_TABS.includes(tab.toLowerCase())) {
421
+ return true;
422
+ }
423
+ }
424
+ return false;
425
+ };
426
+ var isSecurityExclusivePath = (path) => {
427
+ if (!path) return false;
428
+ const clean = path.startsWith("/") ? path : `/${path}`;
429
+ const [pathname] = clean.split("?");
430
+ return SECURITY_EXCLUSIVE_PATH_PREFIXES.some((prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`));
431
+ };
432
+ var resolveProductLink = (href, currentProductOverride) => {
433
+ const currentProduct = getCurrentShuffleProduct(currentProductOverride);
434
+ const trimmed = (href || "").trim();
435
+ if (!trimmed) {
436
+ return { url: "", isInternal: false, targetProduct: "external", isCrossDomainToCore: false };
437
+ }
438
+ if (trimmed.startsWith("#")) {
439
+ return { url: trimmed, isInternal: true, targetProduct: "doc", isCrossDomainToCore: false };
440
+ }
441
+ let pathname = "";
442
+ let searchAndHash = "";
443
+ let isAbsolute = false;
444
+ let isShufflerIoDomain = false;
445
+ let isShuffleSecurityDomain = false;
446
+ try {
447
+ if (/^[a-z][a-z\d+.-]*:/i.test(trimmed)) {
448
+ isAbsolute = true;
449
+ const parsed = new URL(trimmed);
450
+ pathname = parsed.pathname;
451
+ searchAndHash = `${parsed.search}${parsed.hash}`;
452
+ const host = parsed.hostname.toLowerCase();
453
+ if (host === "shuffler.io" || host.endsWith(".shuffler.io") && !host.includes("security.")) {
454
+ isShufflerIoDomain = true;
455
+ } else if (host.includes("shuffle.security") || host.includes("security.shuffler.io")) {
456
+ isShuffleSecurityDomain = true;
457
+ }
458
+ } else {
459
+ const splitIdx = trimmed.search(/[?#]/);
460
+ if (splitIdx !== -1) {
461
+ pathname = trimmed.slice(0, splitIdx);
462
+ searchAndHash = trimmed.slice(splitIdx);
463
+ } else {
464
+ pathname = trimmed;
465
+ }
466
+ }
467
+ } catch {
468
+ pathname = trimmed;
469
+ }
470
+ const fullRelativePath = `${pathname}${searchAndHash}`;
471
+ const isDocPath = /^\/docs(?:\/|$)/i.test(pathname) || /(?:^|\/)\.?\.?\/?[^/#?]+\.md(?:$|[?#])/i.test(trimmed);
472
+ if (isDocPath) {
473
+ return {
474
+ url: fullRelativePath,
475
+ isInternal: true,
476
+ targetProduct: "doc",
477
+ isCrossDomainToCore: false
478
+ };
479
+ }
480
+ const targetsCore = isCoreExclusivePath(fullRelativePath) || isShufflerIoDomain;
481
+ const targetsSecurity = isSecurityExclusivePath(fullRelativePath) || isShuffleSecurityDomain;
482
+ if (targetsCore) {
483
+ if (currentProduct === "core") {
484
+ return {
485
+ url: fullRelativePath,
486
+ isInternal: true,
487
+ targetProduct: "core",
488
+ isCrossDomainToCore: false
489
+ };
490
+ }
491
+ const targetUrl = getShuffleCoreUrl(fullRelativePath);
492
+ return {
493
+ url: targetUrl,
494
+ isInternal: false,
495
+ targetProduct: "core",
496
+ isCrossDomainToCore: true
497
+ };
498
+ }
499
+ if (targetsSecurity) {
500
+ if (currentProduct === "security") {
501
+ return {
502
+ url: fullRelativePath,
503
+ isInternal: true,
504
+ targetProduct: "security",
505
+ isCrossDomainToCore: false
506
+ };
507
+ }
508
+ const targetUrl = getShuffleSecurityUrl(fullRelativePath);
509
+ return {
510
+ url: targetUrl,
511
+ isInternal: false,
512
+ targetProduct: "security",
513
+ isCrossDomainToCore: false
514
+ };
515
+ }
516
+ if (trimmed.startsWith("/")) {
517
+ return {
518
+ url: trimmed,
519
+ isInternal: true,
520
+ targetProduct: currentProduct,
521
+ isCrossDomainToCore: false
522
+ };
523
+ }
524
+ return {
525
+ url: trimmed,
526
+ isInternal: false,
527
+ targetProduct: "external",
528
+ isCrossDomainToCore: false
529
+ };
530
+ };
273
531
 
274
532
  // ../lib/platform.ts
275
533
  var getPlatform = () => {
@@ -328,9 +586,57 @@ if (typeof window !== "undefined") {
328
586
  // api.ts
329
587
  installFetchBreaker();
330
588
  var DEV_BACKEND = "https://tunnel.schemaless.org";
331
- var PROD_BACKEND = "https://uk.shuffler.io";
589
+ var PROD_BACKEND = "https://uk.shuffle.security";
332
590
  var SHUFFLE_AUTOMATION_URL = getShuffleCoreUrl("/new-dashboard");
333
- var CLOUD_DOMAINS = ["shuffle.security", "www.shuffle.security", "security.shuffler.io", "shutdown.no", "www.shutdown.no"];
591
+ var CLOUD_DOMAINS = [
592
+ "shuffle.security",
593
+ "www.shuffle.security",
594
+ "uk.shuffle.security",
595
+ "security.shuffler.io",
596
+ "shuffler.io",
597
+ "shutdown.no",
598
+ "www.shutdown.no"
599
+ ];
600
+ var isShuffleCloudDomain = (url) => {
601
+ if (!url || typeof url !== "string") return false;
602
+ try {
603
+ const raw = url.trim();
604
+ const parsed = new URL(raw.includes("://") ? raw : `https://${raw}`);
605
+ const host = parsed.hostname.toLowerCase();
606
+ return host === "shuffler.io" || host.endsWith(".shuffler.io") || host === "shuffle.security" || host.endsWith(".shuffle.security");
607
+ } catch {
608
+ return false;
609
+ }
610
+ };
611
+ var mapCloudRegionUrl = (url) => {
612
+ if (!url || typeof url !== "string") return "";
613
+ const trimmed = url.trim();
614
+ if (!trimmed) return "";
615
+ const hasScheme = /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(trimmed);
616
+ const toParse = hasScheme ? trimmed : `https://${trimmed}`;
617
+ try {
618
+ const parsed = new URL(toParse);
619
+ const hostname = parsed.hostname.toLowerCase();
620
+ if (hostname === "shuffler.io" || hostname === "www.shuffler.io" || hostname === "shuffle.security" || hostname === "www.shuffle.security") {
621
+ parsed.protocol = "https:";
622
+ parsed.hostname = "uk.shuffle.security";
623
+ return parsed.toString().replace(/\/+$/, "");
624
+ }
625
+ if (hostname.endsWith(".shuffler.io")) {
626
+ const subdomain = hostname.slice(0, -".shuffler.io".length);
627
+ parsed.protocol = "https:";
628
+ parsed.hostname = `${subdomain}.shuffle.security`;
629
+ return parsed.toString().replace(/\/+$/, "");
630
+ }
631
+ if (hostname.endsWith(".shuffle.security")) {
632
+ parsed.protocol = "https:";
633
+ return parsed.toString().replace(/\/+$/, "");
634
+ }
635
+ return trimmed.replace(/\/+$/, "");
636
+ } catch {
637
+ return trimmed.replace(/\/+$/, "");
638
+ }
639
+ };
334
640
  var getEnvVar = (key) => {
335
641
  try {
336
642
  const meta = new Function("try { return import.meta } catch { return undefined }")();
@@ -345,9 +651,12 @@ var isDevEnvironment = () => {
345
651
  return hostname.includes("lovableproject.com") || hostname.includes("id-preview--") || hostname.endsWith(".lovable.app") || hostname.endsWith(".lovable.dev");
346
652
  };
347
653
  var isCloudDomain = () => {
348
- if (isCapacitorNative()) return true;
654
+ if (isCapacitorNative()) {
655
+ if (getHostBaseUrl()) return false;
656
+ return true;
657
+ }
349
658
  const hostname = typeof window !== "undefined" ? window.location.hostname : "";
350
- return CLOUD_DOMAINS.includes(hostname);
659
+ return CLOUD_DOMAINS.includes(hostname) || hostname.endsWith(".shuffle.security") || hostname.endsWith(".shuffler.io");
351
660
  };
352
661
  var isCloud = () => isCloudDomain();
353
662
  var isOnprem = () => !isDevEnvironment() && !isCloudDomain();
@@ -357,7 +666,11 @@ var getDefaultBaseUrl = () => {
357
666
  return envUrl;
358
667
  }
359
668
  if (isDevEnvironment()) return DEV_BACKEND;
360
- if (isCapacitorNative()) return PROD_BACKEND;
669
+ if (isCapacitorNative()) {
670
+ const customHost = getHostBaseUrl();
671
+ if (customHost) return customHost;
672
+ return PROD_BACKEND;
673
+ }
361
674
  if (isCloudDomain()) return PROD_BACKEND;
362
675
  if (typeof window !== "undefined") {
363
676
  return window.location.origin;
@@ -371,11 +684,13 @@ var readCachedRegion = () => {
371
684
  const raw = localStorage.getItem(REGION_STORAGE_KEY);
372
685
  if (!raw) return { url: null, orgId: null };
373
686
  const parsed = JSON.parse(raw);
374
- const url = parsed?.url ? parsed.url.replace(/\/+$/, "") : null;
375
- if (url === "https://shuffler.io" || url === PROD_BACKEND) {
687
+ const rawUrl = parsed?.url ? parsed.url.replace(/\/+$/, "") : null;
688
+ if (!rawUrl) return { url: null, orgId: parsed?.orgId || null };
689
+ const mapped = mapCloudRegionUrl(rawUrl);
690
+ if (mapped === "https://shuffler.io" || mapped === "https://uk.shuffler.io" || mapped === "https://shuffle.security" || mapped === "https://uk.shuffle.security" || mapped === PROD_BACKEND) {
376
691
  return { url: null, orgId: parsed?.orgId || null };
377
692
  }
378
- return { url, orgId: parsed?.orgId || null };
693
+ return { url: mapped, orgId: parsed?.orgId || null };
379
694
  } catch {
380
695
  return { url: null, orgId: null };
381
696
  }
@@ -389,7 +704,23 @@ var readCachedCustomHost = () => {
389
704
  if (mode && mode !== "self-hosted") return null;
390
705
  const raw = localStorage.getItem("shuffle_custom_host_url");
391
706
  const cleaned = raw ? raw.trim().replace(/\/+$/, "") : null;
392
- if (!cleaned) return null;
707
+ if (!cleaned) {
708
+ const host = window.location.hostname.toLowerCase();
709
+ if ((host === "localhost" || host === "127.0.0.1" || host === "[::1]" || host.endsWith(".localhost")) && mode !== "cloud") {
710
+ return "http://localhost:5001";
711
+ }
712
+ return null;
713
+ }
714
+ if (isShuffleCloudDomain(cleaned)) {
715
+ try {
716
+ localStorage.removeItem("shuffle_custom_host_url");
717
+ if (mode === "self-hosted") {
718
+ localStorage.setItem("shuffle_selected_server_mode", "cloud");
719
+ }
720
+ } catch {
721
+ }
722
+ return null;
723
+ }
393
724
  if (cleaned === DEV_BACKEND && !isDevEnvironment() && mode !== "self-hosted") {
394
725
  try {
395
726
  localStorage.removeItem("shuffle_custom_host_url");
@@ -437,23 +768,28 @@ if (typeof window !== "undefined") {
437
768
  if (e.key === REGION_STORAGE_KEY) sync();
438
769
  });
439
770
  }
440
- var isShufflerSubdomain = (url) => {
441
- try {
442
- const parsed = new URL(url);
443
- return parsed.hostname.endsWith(".shuffler.io") || parsed.hostname === "shuffler.io";
444
- } catch {
445
- return false;
446
- }
447
- };
448
771
  var setRegionUrl = (regionUrl, orgId) => {
449
772
  _trackedOrgId = orgId || null;
450
- if (regionUrl && isShufflerSubdomain(regionUrl)) {
451
- const normalized = regionUrl.replace(/\/+$/, "");
452
- const isDefaultCloud = normalized === PROD_BACKEND || normalized === "https://shuffler.io";
453
- if (!isDefaultCloud) {
454
- _regionUrl = normalized;
773
+ if (regionUrl) {
774
+ const isSelfHosted = !isCloudDomain() || Boolean(_hostBaseUrl);
775
+ if (isShuffleCloudDomain(regionUrl)) {
776
+ if (isSelfHosted) {
777
+ _regionUrl = null;
778
+ persistRegion(null, _trackedOrgId);
779
+ return;
780
+ }
781
+ const mapped = mapCloudRegionUrl(regionUrl);
782
+ const normalized = mapped.replace(/\/+$/, "");
783
+ const isDefaultCloud = normalized === PROD_BACKEND || normalized === "https://shuffler.io" || normalized === "https://uk.shuffler.io" || normalized === "https://shuffle.security" || normalized === "https://uk.shuffle.security";
784
+ if (!isDefaultCloud) {
785
+ _regionUrl = normalized;
786
+ persistRegion(_regionUrl, _trackedOrgId);
787
+ console.log(`[API] Region URL set to: ${_regionUrl}`);
788
+ return;
789
+ }
790
+ } else {
791
+ _regionUrl = regionUrl.replace(/\/+$/, "");
455
792
  persistRegion(_regionUrl, _trackedOrgId);
456
- console.log(`[API] Region URL set to: ${_regionUrl}`);
457
793
  return;
458
794
  }
459
795
  }
@@ -463,7 +799,8 @@ var setRegionUrl = (regionUrl, orgId) => {
463
799
  var applyRegionFromPayload = (payload, orgIdOverride) => {
464
800
  if (!payload || typeof payload !== "object") return null;
465
801
  const orgId = orgIdOverride ?? payload?.active_org?.id ?? payload?.org_id ?? null;
466
- const regionUrl = payload?.region_url || payload?.active_org?.region_url || null;
802
+ const rawRegionUrl = payload?.region_url || payload?.active_org?.region_url || null;
803
+ const regionUrl = rawRegionUrl ? mapCloudRegionUrl(rawRegionUrl) : null;
467
804
  setRegionUrl(regionUrl, orgId);
468
805
  return regionUrl;
469
806
  };
@@ -518,9 +855,12 @@ var getSessionToken = () => {
518
855
  localStorage.removeItem(LEGACY_API_KEY_STORAGE_KEY);
519
856
  }
520
857
  const stored = localStorage.getItem("session_token");
521
- if (stored && stored.trim().length > 0 && stored !== "null" && stored !== "undefined") {
858
+ if (stored && stored.trim().length > 0 && stored !== "null" && stored !== "undefined" && stored !== "authenticated" && stored !== "session" && stored !== "cookie-session") {
522
859
  return stored.trim();
523
860
  }
861
+ if (stored === "authenticated" || stored === "session" || stored === "cookie-session") {
862
+ localStorage.removeItem("session_token");
863
+ }
524
864
  return null;
525
865
  } catch {
526
866
  return null;
@@ -528,13 +868,62 @@ var getSessionToken = () => {
528
868
  };
529
869
  var setSessionToken = (token) => {
530
870
  clearAuthTokens();
531
- if (token && token.trim().length > 0) {
871
+ if (token && token.trim().length > 0 && token !== "authenticated" && token !== "session" && token !== "cookie-session" && token !== "null" && token !== "undefined") {
532
872
  try {
533
873
  localStorage.setItem("session_token", token.trim());
534
874
  } catch {
535
875
  }
536
876
  }
537
877
  };
878
+ var isShuffleSecurityBackend = (backendUrl) => {
879
+ try {
880
+ const backend = backendUrl || API_CONFIG.baseUrl || "";
881
+ if (backend) {
882
+ const parsed = new URL(backend.includes("://") ? backend : `https://${backend}`);
883
+ const host = parsed.hostname.toLowerCase();
884
+ if (host === "shuffle.security" || host.endsWith(".shuffle.security") || host === "shuffler.io" || host.endsWith(".shuffler.io")) {
885
+ return true;
886
+ }
887
+ }
888
+ } catch {
889
+ }
890
+ if (typeof window !== "undefined") {
891
+ try {
892
+ const windowHost = window.location.hostname.toLowerCase();
893
+ if (windowHost === "shuffle.security" || windowHost.endsWith(".shuffle.security") || windowHost === "shuffler.io" || windowHost.endsWith(".shuffler.io")) {
894
+ return true;
895
+ }
896
+ } catch {
897
+ }
898
+ }
899
+ return false;
900
+ };
901
+ var isCrossDomainBackend = (targetUrl) => {
902
+ if (typeof window === "undefined") return false;
903
+ try {
904
+ const backendUrl = targetUrl || API_CONFIG.baseUrl;
905
+ if (!backendUrl) return false;
906
+ const backendHost = new URL(backendUrl, window.location.origin).hostname.toLowerCase();
907
+ const frontendHost = window.location.hostname.toLowerCase();
908
+ if (backendHost === frontendHost) return false;
909
+ const isLocalFrontend = frontendHost === "localhost" || frontendHost === "127.0.0.1";
910
+ const isLocalBackend = backendHost === "localhost" || backendHost === "127.0.0.1";
911
+ if (isLocalFrontend && isLocalBackend) return false;
912
+ const getRootDomain = (host) => {
913
+ const parts = host.split(".");
914
+ if (parts.length <= 2) return host;
915
+ return parts.slice(-2).join(".");
916
+ };
917
+ const frontendRoot = getRootDomain(frontendHost);
918
+ const backendRoot = getRootDomain(backendHost);
919
+ if (frontendRoot && backendRoot && frontendRoot === backendRoot) {
920
+ return false;
921
+ }
922
+ return true;
923
+ } catch {
924
+ return false;
925
+ }
926
+ };
538
927
  var API_CONFIG = {
539
928
  // Shuffle backend URL — host override beats region URL beats default.
540
929
  get baseUrl() {
@@ -575,8 +964,9 @@ var shuffleFetch = (url, init) => {
575
964
  };
576
965
  var getAuthHeader = (overrideOrgId) => {
577
966
  const headers = {};
967
+ const authMode = typeof localStorage !== "undefined" ? localStorage.getItem("shuffle_auth_mode") : null;
578
968
  const token = getSessionToken();
579
- if (token) {
969
+ if (token && (authMode === "bearer" || isCapacitorNative() || isCrossDomainBackend())) {
580
970
  headers["Authorization"] = `Bearer ${token}`;
581
971
  }
582
972
  let orgId = overrideOrgId ?? _trackedOrgId;
@@ -661,9 +1051,12 @@ var fetchAppsViaApiConfig = () => {
661
1051
  };
662
1052
 
663
1053
  export {
1054
+ resolveProductLink,
664
1055
  registerProtectedOrigin,
665
1056
  installFetchBreaker,
666
1057
  isCapacitorNative,
1058
+ isShuffleCloudDomain,
1059
+ mapCloudRegionUrl,
667
1060
  isCloudDomain,
668
1061
  isCloud,
669
1062
  isOnprem,
@@ -673,6 +1066,7 @@ export {
673
1066
  setHostBaseUrl,
674
1067
  getHostBaseUrl,
675
1068
  getTrackedOrgId,
1069
+ isShuffleSecurityBackend,
676
1070
  API_CONFIG,
677
1071
  getApiUrl,
678
1072
  shuffleFetch,