@eeacms/volto-arcgis-block 0.1.483 → 0.1.485
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/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [0.1.485](https://github.com/eea/volto-arcgis-block/compare/0.1.484...0.1.485) - 24 September 2026
|
|
8
|
+
|
|
9
|
+
#### :hammer_and_wrench: Others
|
|
10
|
+
|
|
11
|
+
- (lint): lint and prettified [Unai Bolivar - [`6caacff`](https://github.com/eea/volto-arcgis-block/commit/6caacffcda92259d4ecd9e5ba0aedea28c0999e1)]
|
|
12
|
+
- (bug): removed additional zoom on extent behavior [Unai Bolivar - [`b609753`](https://github.com/eea/volto-arcgis-block/commit/b6097536b13e94cd1772c0528a6ea984fb497fcb)]
|
|
13
|
+
- (bug): parse CDSE WMTS capabilities identifiers correctly [Unai Bolivar - [`a3c9f4b`](https://github.com/eea/volto-arcgis-block/commit/a3c9f4b285c916a0adf45168cab85950a4415890)]
|
|
14
|
+
### [0.1.484](https://github.com/eea/volto-arcgis-block/compare/0.1.483...0.1.484) - 15 September 2026
|
|
15
|
+
|
|
16
|
+
#### :hammer_and_wrench: Others
|
|
17
|
+
|
|
18
|
+
- (lint): lint and prettified [Unai Bolivar - [`13294af`](https://github.com/eea/volto-arcgis-block/commit/13294aff5e09463006cbc6421800c8f71bd4ac49)]
|
|
7
19
|
### [0.1.483](https://github.com/eea/volto-arcgis-block/compare/0.1.482...0.1.483) - 15 September 2026
|
|
8
20
|
|
|
9
21
|
### [0.1.482](https://github.com/eea/volto-arcgis-block/compare/0.1.481...0.1.482) - 15 September 2026
|
package/package.json
CHANGED
|
@@ -577,10 +577,29 @@ class InfoWidget extends React.Component {
|
|
|
577
577
|
}
|
|
578
578
|
|
|
579
579
|
identifyWMTS(layer, event) {
|
|
580
|
-
let layerId = layer.activeLayer.id;
|
|
581
580
|
let url = layer.featureInfoUrl ? layer.featureInfoUrl : layer.url;
|
|
582
581
|
let featureInfoUrl = url.replace('/cdse/', '/cdse/wms/');
|
|
583
582
|
return this.wmsCapabilities(url).then((xml) => {
|
|
583
|
+
let serviceData = layer.ViewService ? layer.ViewService : url;
|
|
584
|
+
let isCdseWmts = ['/ogc/', '/cdse/'].some((segment) =>
|
|
585
|
+
serviceData.toLowerCase().includes(segment),
|
|
586
|
+
);
|
|
587
|
+
let layerId;
|
|
588
|
+
if (isCdseWmts) {
|
|
589
|
+
let wmtsLayers = Array.from(xml.querySelectorAll('Layer'));
|
|
590
|
+
let layerTitle = this.getLayerTitle(layer);
|
|
591
|
+
let selectedLayer = wmtsLayers.find((item) => {
|
|
592
|
+
let titleNode =
|
|
593
|
+
item.querySelector('ows\\:Title') || item.querySelector('Title');
|
|
594
|
+
return titleNode && titleNode.textContent === layerTitle;
|
|
595
|
+
});
|
|
596
|
+
layerId = (
|
|
597
|
+
selectedLayer.querySelector('ows\\:Identifier') ||
|
|
598
|
+
selectedLayer.querySelector('Identifier')
|
|
599
|
+
).textContent;
|
|
600
|
+
} else {
|
|
601
|
+
layerId = layer.activeLayer.id;
|
|
602
|
+
}
|
|
584
603
|
let version = layer.version;
|
|
585
604
|
let format = this.parseFormat(xml, layerId);
|
|
586
605
|
let times = '';
|
|
@@ -7,6 +7,7 @@ import useCartState from '@eeacms/volto-clms-utils/cart/useCartState';
|
|
|
7
7
|
import { Modal, Popup } from 'semantic-ui-react';
|
|
8
8
|
import AreaWidget from './AreaWidget';
|
|
9
9
|
import TimesliderWidget from './TimesliderWidget';
|
|
10
|
+
import { resolveServiceUrl } from './serviceUrlResolver';
|
|
10
11
|
|
|
11
12
|
export const USER_SERVICES_KEY = 'user_services_session';
|
|
12
13
|
|
|
@@ -479,24 +480,12 @@ class MenuWidget extends React.Component {
|
|
|
479
480
|
// add zoomend listener to map to show/hide zoom in message
|
|
480
481
|
this.view.watch('stationary', (isStationary) => {
|
|
481
482
|
let snowAndIceInSessionStorage = sessionStorage.getItem('snowAndIce');
|
|
482
|
-
let node;
|
|
483
483
|
if (this.view && this.view.center) {
|
|
484
484
|
this.extentCenter = { x: this.view.center.x, y: this.view.center.y };
|
|
485
485
|
}
|
|
486
486
|
if (isStationary) {
|
|
487
487
|
this.extentInitiated = false;
|
|
488
|
-
let zoom = this.view.get('zoom');
|
|
489
|
-
if (this.props.download) {
|
|
490
|
-
node = document.querySelector('.zoom-in-message-dataset');
|
|
491
|
-
if (node && node !== null) {
|
|
492
|
-
node.style.display = zoom > 6 ? 'none' : 'block';
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
488
|
if (!this.props.download && snowAndIceInSessionStorage === 'true') {
|
|
496
|
-
node = document.getElementById('snow-and-ice-zoom-message');
|
|
497
|
-
if (node && node !== null) {
|
|
498
|
-
node.style.display = zoom > 6 ? 'none' : 'block';
|
|
499
|
-
}
|
|
500
489
|
let innerDropdown = document.getElementsByClassName(
|
|
501
490
|
'map-product-checkbox',
|
|
502
491
|
);
|
|
@@ -521,41 +510,7 @@ class MenuWidget extends React.Component {
|
|
|
521
510
|
snowAndIce.offsetParent.nextSibling === null
|
|
522
511
|
)
|
|
523
512
|
return;
|
|
524
|
-
let checks = snowAndIce.offsetParent.nextSibling.children;
|
|
525
|
-
let checksList = [...checks];
|
|
526
|
-
if (checksList && checksList !== null) {
|
|
527
|
-
checksList.forEach((check) => {
|
|
528
|
-
if (check && check !== null) {
|
|
529
|
-
if (check.querySelector('[type="checkbox"]').checked) {
|
|
530
|
-
let node = [
|
|
531
|
-
...check.getElementsByClassName('zoom-in-message-dataset'),
|
|
532
|
-
][0];
|
|
533
|
-
if (node && node !== null) {
|
|
534
|
-
node.style.display = zoom > 6 ? 'none' : 'block';
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
513
|
}
|
|
541
|
-
let zoomInMessageContainers = document.getElementsByClassName(
|
|
542
|
-
'zoom-in-message-container',
|
|
543
|
-
);
|
|
544
|
-
let zoomInMessageContainersList = [...zoomInMessageContainers];
|
|
545
|
-
zoomInMessageContainersList.forEach((container) => {
|
|
546
|
-
if (container && container !== null) {
|
|
547
|
-
let nodes = [
|
|
548
|
-
...document.getElementsByClassName('zoom-in-message-dataset'),
|
|
549
|
-
];
|
|
550
|
-
nodes.forEach((node) => {
|
|
551
|
-
if (node && node !== null) {
|
|
552
|
-
if (node.innerText === 'Zoom in') {
|
|
553
|
-
node.style.display = zoom > 6 ? 'none' : 'block';
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
514
|
if (!this.visibleLayers) this.visibleLayers = {};
|
|
560
515
|
this.handleRasterVectorLegend();
|
|
561
516
|
this.setState({});
|
|
@@ -2661,28 +2616,6 @@ class MenuWidget extends React.Component {
|
|
|
2661
2616
|
);
|
|
2662
2617
|
}
|
|
2663
2618
|
|
|
2664
|
-
stripProtocol(url) {
|
|
2665
|
-
return (url || '').replace(/^https?:\/\//i, '');
|
|
2666
|
-
}
|
|
2667
|
-
|
|
2668
|
-
getProxyBase = () => {
|
|
2669
|
-
const origin = window?.location?.origin || '';
|
|
2670
|
-
return origin ? `${origin}/ogcproxy/` : '/ogcproxy/';
|
|
2671
|
-
// return 'https://clmsdemo.devel6cph.eea.europa.eu/ogcproxy/';
|
|
2672
|
-
// return 'https://land.copernicus.eu/ogcproxy/';
|
|
2673
|
-
};
|
|
2674
|
-
|
|
2675
|
-
buildProxiedUrl(url) {
|
|
2676
|
-
if (!url) return url;
|
|
2677
|
-
const hasProxy = /\/ogcproxy\//i.test(url);
|
|
2678
|
-
if (hasProxy) {
|
|
2679
|
-
const strippedUrl = this.stripProtocol(url);
|
|
2680
|
-
const proxyPath = strippedUrl.split(/\/ogcproxy\//i)[1] || '';
|
|
2681
|
-
return this.getProxyBase() + proxyPath.replace(/^\/+/, '');
|
|
2682
|
-
}
|
|
2683
|
-
return this.getProxyBase() + this.stripProtocol(url);
|
|
2684
|
-
}
|
|
2685
|
-
|
|
2686
2619
|
buildCdseLegendUrl(serviceUrl, layerTitle) {
|
|
2687
2620
|
if (!serviceUrl || !layerTitle) return null;
|
|
2688
2621
|
const collectionMatch =
|
|
@@ -3657,9 +3590,11 @@ class MenuWidget extends React.Component {
|
|
|
3657
3590
|
|
|
3658
3591
|
async handleNewMapServiceLayer(viewService, serviceType, serviceSelection) {
|
|
3659
3592
|
let resourceLayers = [];
|
|
3660
|
-
const
|
|
3593
|
+
const resolvedServiceUrl = resolveServiceUrl(viewService, {
|
|
3594
|
+
fromUploadWidget: true,
|
|
3595
|
+
});
|
|
3661
3596
|
try {
|
|
3662
|
-
const rawUrl = (
|
|
3597
|
+
const rawUrl = (resolvedServiceUrl || '').trim();
|
|
3663
3598
|
const baseUrl = rawUrl.split('?')[0];
|
|
3664
3599
|
const resolveCapabilitiesText = (xmlData) => {
|
|
3665
3600
|
if (!xmlData) {
|
|
@@ -4034,7 +3969,7 @@ class MenuWidget extends React.Component {
|
|
|
4034
3969
|
}
|
|
4035
3970
|
}
|
|
4036
3971
|
if (serviceType === 'WMS' || serviceType === 'WMTS') {
|
|
4037
|
-
const forced = (
|
|
3972
|
+
const forced = (resolvedServiceUrl || '').trim();
|
|
4038
3973
|
if (forced) {
|
|
4039
3974
|
if (typeof resourceLayer.url === 'string') {
|
|
4040
3975
|
resourceLayer.url = forced;
|
|
@@ -6195,7 +6130,9 @@ class MenuWidget extends React.Component {
|
|
|
6195
6130
|
|
|
6196
6131
|
getCapabilities = async (url, serviceType, options = {}) => {
|
|
6197
6132
|
const useProxy = !!options?.useProxy;
|
|
6198
|
-
const targetUrl = useProxy
|
|
6133
|
+
const targetUrl = useProxy
|
|
6134
|
+
? resolveServiceUrl(url, { fromUploadWidget: true })
|
|
6135
|
+
: url;
|
|
6199
6136
|
const evaluateXmlResponse = (responseData) => {
|
|
6200
6137
|
const parser = new DOMParser();
|
|
6201
6138
|
const xmlDoc = parser.parseFromString(responseData, 'text/xml');
|
|
@@ -6438,35 +6375,7 @@ class MenuWidget extends React.Component {
|
|
|
6438
6375
|
ymax: BBoxes['dataset'].ymax,
|
|
6439
6376
|
});
|
|
6440
6377
|
}
|
|
6441
|
-
|
|
6442
|
-
this.extentInitiated === false &&
|
|
6443
|
-
(this.layers[elem.id].DatasetId === '65f8eded11d94a1ba5540ceecaddd4e6' ||
|
|
6444
|
-
this.layers[elem.id].DatasetId === '40e056d02eed4c1fb2040cf0f06823df')
|
|
6445
|
-
) {
|
|
6446
|
-
let myExtent = new Extent({
|
|
6447
|
-
xmin: -13478905.5678019,
|
|
6448
|
-
ymin: 23797904.386302948,
|
|
6449
|
-
xmax: 20538395.093334593,
|
|
6450
|
-
ymax: 11175665.272476234,
|
|
6451
|
-
spatialReference: 3857,
|
|
6452
|
-
});
|
|
6453
|
-
const targetCenter = myExtent.center;
|
|
6454
|
-
if (this.extentCenter) {
|
|
6455
|
-
const epsilon = 1e-3;
|
|
6456
|
-
const sameStoredCenter =
|
|
6457
|
-
Math.abs(this.extentCenter.x - targetCenter.x) < epsilon &&
|
|
6458
|
-
Math.abs(this.extentCenter.y - targetCenter.y) < epsilon;
|
|
6459
|
-
if (sameStoredCenter) {
|
|
6460
|
-
this.extentInitiated = true;
|
|
6461
|
-
return;
|
|
6462
|
-
}
|
|
6463
|
-
}
|
|
6464
|
-
this.view.goTo({ center: targetCenter, zoom: 3 });
|
|
6465
|
-
this.extentCenter = { x: targetCenter.x, y: targetCenter.y };
|
|
6466
|
-
this.extentInitiated = true;
|
|
6467
|
-
} else {
|
|
6468
|
-
this.view.goTo(myExtent);
|
|
6469
|
-
}
|
|
6378
|
+
this.view.goTo(myExtent);
|
|
6470
6379
|
}
|
|
6471
6380
|
|
|
6472
6381
|
async fullExtent(elem) {
|
|
@@ -6819,42 +6728,7 @@ class MenuWidget extends React.Component {
|
|
|
6819
6728
|
xmax: firstLayer.xmax,
|
|
6820
6729
|
ymax: firstLayer.ymax,
|
|
6821
6730
|
});
|
|
6822
|
-
|
|
6823
|
-
this.extentInitiated === false &&
|
|
6824
|
-
(this.layers[elem.id].DatasetId ===
|
|
6825
|
-
'65f8eded11d94a1ba5540ceecaddd4e6' ||
|
|
6826
|
-
this.layers[elem.id].DatasetId === '40e056d02eed4c1fb2040cf0f06823df')
|
|
6827
|
-
) {
|
|
6828
|
-
let myExtent = new Extent({
|
|
6829
|
-
xmin: -13478905.5678019,
|
|
6830
|
-
ymin: 23797904.386302948,
|
|
6831
|
-
xmax: 20538395.093334593,
|
|
6832
|
-
ymax: 11175665.272476234,
|
|
6833
|
-
spatialReference: 3857,
|
|
6834
|
-
});
|
|
6835
|
-
const targetCenter = myExtent.center;
|
|
6836
|
-
if (this.extentCenter) {
|
|
6837
|
-
const epsilon = 1e-3;
|
|
6838
|
-
const sameStoredCenter =
|
|
6839
|
-
Math.abs(this.extentCenter.x - targetCenter.x) < epsilon &&
|
|
6840
|
-
Math.abs(this.extentCenter.y - targetCenter.y) < epsilon;
|
|
6841
|
-
if (sameStoredCenter) {
|
|
6842
|
-
if (this.toggleHotspotWidget.view.zoom !== 3) {
|
|
6843
|
-
this.view.zoom = 3;
|
|
6844
|
-
this.setState({}); // Force re-render
|
|
6845
|
-
return;
|
|
6846
|
-
} else {
|
|
6847
|
-
this.extentInitiated = true;
|
|
6848
|
-
return;
|
|
6849
|
-
}
|
|
6850
|
-
}
|
|
6851
|
-
}
|
|
6852
|
-
this.view.goTo({ center: targetCenter, zoom: 3 });
|
|
6853
|
-
this.extentCenter = { x: targetCenter.x, y: targetCenter.y };
|
|
6854
|
-
this.extentInitiated = true;
|
|
6855
|
-
} else {
|
|
6856
|
-
this.view.goTo(myExtent);
|
|
6857
|
-
}
|
|
6731
|
+
this.view.goTo(myExtent);
|
|
6858
6732
|
}
|
|
6859
6733
|
this.url = null;
|
|
6860
6734
|
}
|
|
@@ -2,6 +2,7 @@ import React, { createRef } from 'react';
|
|
|
2
2
|
import { loadModules } from 'esri-loader';
|
|
3
3
|
// import { FontAwesomeIcon } from '@eeacms/volto-clms-utils/components';
|
|
4
4
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
5
|
+
import { resolveServiceUrl } from './serviceUrlResolver';
|
|
5
6
|
|
|
6
7
|
var WMSLayer, WMTSLayer, WFSLayer, esriRequest;
|
|
7
8
|
const SHAPEFILE_MAX_SIZE_BYTES = 2097152;
|
|
@@ -334,28 +335,6 @@ class UploadWidget extends React.Component {
|
|
|
334
335
|
this.clearUploadForm(true);
|
|
335
336
|
};
|
|
336
337
|
|
|
337
|
-
stripProtocol = (url) => {
|
|
338
|
-
return (url || '').replace(/^https?:\/\//i, '');
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
getProxyBase = () => {
|
|
342
|
-
const origin = window?.location?.origin || '';
|
|
343
|
-
return origin ? `${origin}/ogcproxy/` : '/ogcproxy/';
|
|
344
|
-
// return 'https://clmsdemo.devel6cph.eea.europa.eu/ogcproxy/';
|
|
345
|
-
// return 'https://land.copernicus.eu/ogcproxy/';
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
buildProxiedUrl = (url) => {
|
|
349
|
-
if (!url) return url;
|
|
350
|
-
const hasProxy = /\/ogcproxy\//i.test(url);
|
|
351
|
-
if (hasProxy) {
|
|
352
|
-
const strippedUrl = this.stripProtocol(url);
|
|
353
|
-
const proxyPath = strippedUrl.split(/\/ogcproxy\//i)[1] || '';
|
|
354
|
-
return this.getProxyBase() + proxyPath.replace(/^\/+/, '');
|
|
355
|
-
}
|
|
356
|
-
return this.getProxyBase() + this.stripProtocol(url);
|
|
357
|
-
};
|
|
358
|
-
|
|
359
338
|
resolveNodeValue = (nodeValue) => {
|
|
360
339
|
if (nodeValue === null || nodeValue === undefined) {
|
|
361
340
|
return null;
|
|
@@ -510,8 +489,10 @@ class UploadWidget extends React.Component {
|
|
|
510
489
|
|
|
511
490
|
getCapabilities = (url, serviceType) => {
|
|
512
491
|
// Get the coordinates of the click on the view
|
|
513
|
-
const
|
|
514
|
-
|
|
492
|
+
const resolvedServiceUrl = resolveServiceUrl(url, {
|
|
493
|
+
fromUploadWidget: true,
|
|
494
|
+
});
|
|
495
|
+
return esriRequest(resolvedServiceUrl, {
|
|
515
496
|
responseType: 'text',
|
|
516
497
|
query: {
|
|
517
498
|
request: 'GetCapabilities',
|
|
@@ -617,15 +598,21 @@ class UploadWidget extends React.Component {
|
|
|
617
598
|
trimmedServiceUrl,
|
|
618
599
|
selectedServiceType,
|
|
619
600
|
);
|
|
620
|
-
const
|
|
601
|
+
const resolvedServiceUrl = resolveServiceUrl(normalizedUrl, {
|
|
602
|
+
fromUploadWidget: true,
|
|
603
|
+
});
|
|
621
604
|
if (selectedServiceType === 'WMS') {
|
|
622
|
-
this.uploadUrlServiceHandler(
|
|
605
|
+
this.uploadUrlServiceHandler(resolvedServiceUrl, 'WMS');
|
|
623
606
|
this.setState({ serviceUrl: '' });
|
|
624
607
|
} else if (selectedServiceType === 'WMTS') {
|
|
625
|
-
this.uploadUrlServiceHandler(
|
|
608
|
+
this.uploadUrlServiceHandler(resolvedServiceUrl, 'WMTS');
|
|
626
609
|
this.setState({ serviceUrl: '' });
|
|
627
610
|
} else if (selectedServiceType === 'WFS') {
|
|
628
|
-
this.uploadUrlServiceHandler(
|
|
611
|
+
this.uploadUrlServiceHandler(
|
|
612
|
+
resolvedServiceUrl,
|
|
613
|
+
'WFS',
|
|
614
|
+
selectedFeatures,
|
|
615
|
+
);
|
|
629
616
|
this.setState({ wfsFeatures: {}, serviceUrl: '' });
|
|
630
617
|
this.setState({ selectedFeatures: {} });
|
|
631
618
|
} else {
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
const PROXY_PATH_PATTERN = /\/ogcproxy\//i;
|
|
2
|
+
const INTERNAL_HOST_PATTERNS = [
|
|
3
|
+
/^localhost$/i,
|
|
4
|
+
/^127\.0\.0\.1$/i,
|
|
5
|
+
/^0\.0\.0\.0$/i,
|
|
6
|
+
/(^|\.)land\.copernicus\.eu$/i,
|
|
7
|
+
/(^|\.)clms-staging\.eea\.europa\.eu$/i,
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
const stripProtocol = (url) => {
|
|
11
|
+
return (url || '').replace(/^https?:\/\//i, '');
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const getProxyBase = () => {
|
|
15
|
+
const origin = window?.location?.origin || '';
|
|
16
|
+
return origin ? `${origin}/ogcproxy/` : '/ogcproxy/';
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const resolveAbsoluteUrl = (url) => {
|
|
20
|
+
if (!url || typeof url !== 'string') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
return new URL(url, window?.location?.origin || undefined);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const isRelativeUrl = (url) => {
|
|
31
|
+
if (!url || typeof url !== 'string') {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return !/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(url);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const isInternalHost = (hostname, currentHostname) => {
|
|
38
|
+
const hostValue = String(hostname || '').toLowerCase();
|
|
39
|
+
const currentHostValue = String(currentHostname || '').toLowerCase();
|
|
40
|
+
if (!hostValue) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (
|
|
44
|
+
INTERNAL_HOST_PATTERNS.some((hostPattern) => hostPattern.test(hostValue))
|
|
45
|
+
) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (currentHostValue && hostValue === currentHostValue) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (currentHostValue && hostValue.endsWith(`.${currentHostValue}`)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
if (currentHostValue && currentHostValue.endsWith(`.${hostValue}`)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const isInternalAbsoluteUrl = (absoluteUrl) => {
|
|
61
|
+
if (!absoluteUrl) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const currentOrigin = window?.location?.origin || '';
|
|
65
|
+
const currentHostname = window?.location?.hostname || '';
|
|
66
|
+
if (currentOrigin && absoluteUrl.origin === currentOrigin) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
return isInternalHost(absoluteUrl.hostname, currentHostname);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const resolveUnproxiedUrl = (inputUrl) => {
|
|
73
|
+
if (!inputUrl || !PROXY_PATH_PATTERN.test(inputUrl)) {
|
|
74
|
+
return inputUrl;
|
|
75
|
+
}
|
|
76
|
+
const strippedUrl = stripProtocol(inputUrl);
|
|
77
|
+
const proxyPathData = strippedUrl.split(PROXY_PATH_PATTERN)[1] || '';
|
|
78
|
+
const normalizedPathData = proxyPathData.replace(/^\/+/, '');
|
|
79
|
+
if (!normalizedPathData) {
|
|
80
|
+
return inputUrl;
|
|
81
|
+
}
|
|
82
|
+
if (/^https?:\/\//i.test(normalizedPathData)) {
|
|
83
|
+
return normalizedPathData;
|
|
84
|
+
}
|
|
85
|
+
const secureProtocol =
|
|
86
|
+
window?.location?.protocol === 'http:' ? 'http://' : 'https://';
|
|
87
|
+
return secureProtocol + normalizedPathData;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const resolveServiceUrl = (url, options = {}) => {
|
|
91
|
+
if (!url || typeof url !== 'string') {
|
|
92
|
+
return url;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!options.fromUploadWidget) {
|
|
96
|
+
return url;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const trimmedUrl = url.trim();
|
|
100
|
+
if (!trimmedUrl) {
|
|
101
|
+
return trimmedUrl;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (/^(blob:|data:|about:)/i.test(trimmedUrl)) {
|
|
105
|
+
return trimmedUrl;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (isRelativeUrl(trimmedUrl) && !PROXY_PATH_PATTERN.test(trimmedUrl)) {
|
|
109
|
+
return trimmedUrl;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const alreadyProxied = PROXY_PATH_PATTERN.test(trimmedUrl);
|
|
113
|
+
const unproxiedUrl = resolveUnproxiedUrl(trimmedUrl);
|
|
114
|
+
const absoluteUrl = resolveAbsoluteUrl(unproxiedUrl);
|
|
115
|
+
|
|
116
|
+
if (!absoluteUrl) {
|
|
117
|
+
return trimmedUrl;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (isInternalAbsoluteUrl(absoluteUrl)) {
|
|
121
|
+
return absoluteUrl.toString();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const normalizedExternalUrl = stripProtocol(absoluteUrl.toString());
|
|
125
|
+
if (alreadyProxied) {
|
|
126
|
+
const proxyPathData = normalizedExternalUrl.replace(/^\/+/, '');
|
|
127
|
+
return getProxyBase() + proxyPathData;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return getProxyBase() + normalizedExternalUrl;
|
|
131
|
+
};
|