@itwin/ecschema-rpcinterface-tests 5.13.0-dev.16 → 5.13.0-dev.18
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/lib/dist/bundled-tests.js +591 -96
- package/lib/dist/bundled-tests.js.map +1 -1
- package/lib/dist/core_frontend_lib_esm_ApproximateTerrainHeightsProps_js.bundled-tests.js.map +1 -1
- package/lib/dist/vendors-common_temp_node_modules_pnpm_cross-fetch_4_1_0_node_modules_cross-fetch_dist_browser-44272f.bundled-tests.js.map +1 -1
- package/lib/dist/vendors-common_temp_node_modules_pnpm_loaders_gl_draco_4_3_4__loaders_gl_core_4_3_4_node_modu-4c1fc9.bundled-tests.js.map +1 -1
- package/package.json +15 -15
|
@@ -91445,6 +91445,8 @@ const COPYRIGHT_NOTICE = `Copyright © 2017-${new Date().getFullYear()} <a href=
|
|
|
91445
91445
|
|
|
91446
91446
|
|
|
91447
91447
|
|
|
91448
|
+
/** CSS class name applied to the notice element of a logo card created by [[IModelApp.makeLogoCard]]. */
|
|
91449
|
+
const logoCardNoticeClassName = "logo-cards";
|
|
91448
91450
|
/**
|
|
91449
91451
|
* Global singleton that connects the user interface with the iTwin.js services. There can be only one IModelApp active in a session. All
|
|
91450
91452
|
* members of IModelApp are static, and it serves as a singleton object for gaining access to session information.
|
|
@@ -91957,10 +91959,21 @@ class IModelApp {
|
|
|
91957
91959
|
}
|
|
91958
91960
|
if (undefined !== opts.notice) {
|
|
91959
91961
|
if (typeof opts.notice === "string")
|
|
91960
|
-
IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className:
|
|
91962
|
+
IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className: logoCardNoticeClassName });
|
|
91961
91963
|
else
|
|
91962
91964
|
noticeCell.appendChild(opts.notice);
|
|
91963
91965
|
}
|
|
91966
|
+
else if (undefined !== opts.noticeLines) {
|
|
91967
|
+
// A <p> cannot legally contain flow content, so use a <div> when a line is an element.
|
|
91968
|
+
const containerTag = opts.noticeLines.some((line) => typeof line !== "string") ? "div" : "p";
|
|
91969
|
+
const notice = IModelApp.makeHTMLElement(containerTag, { parent: noticeCell, className: logoCardNoticeClassName });
|
|
91970
|
+
opts.noticeLines.forEach((line, index) => {
|
|
91971
|
+
if (index > 0)
|
|
91972
|
+
notice.appendChild(IModelApp.makeHTMLElement("br"));
|
|
91973
|
+
// Strings are appended as text nodes so they are never parsed as HTML.
|
|
91974
|
+
notice.append(line);
|
|
91975
|
+
});
|
|
91976
|
+
}
|
|
91964
91977
|
return card;
|
|
91965
91978
|
}
|
|
91966
91979
|
/** Make the logo card for the library itself. This card gets placed at the top of the stack.
|
|
@@ -93527,7 +93540,9 @@ let iModelJsCss = `
|
|
|
93527
93540
|
|
|
93528
93541
|
.logo-cards {
|
|
93529
93542
|
position:relative;
|
|
93530
|
-
width:100
|
|
93543
|
+
width:100%;
|
|
93544
|
+
margin-block-start:1em;
|
|
93545
|
+
margin-block-end:1em
|
|
93531
93546
|
}
|
|
93532
93547
|
|
|
93533
93548
|
.imodeljs-modal-overlay {
|
|
@@ -93571,7 +93586,7 @@ let iModelJsCss = `
|
|
|
93571
93586
|
max-width: calc(100% - (2 * var(--width-border))) !important;
|
|
93572
93587
|
width: unset !important;
|
|
93573
93588
|
}
|
|
93574
|
-
.imodeljs-about .logo-card-message p {
|
|
93589
|
+
.imodeljs-about .logo-card-message p, .imodeljs-about .logo-card-message .logo-cards {
|
|
93575
93590
|
margin-block-end: 1em;
|
|
93576
93591
|
}
|
|
93577
93592
|
.imodeljs-about .logo-cards {
|
|
@@ -96217,9 +96232,12 @@ class Google3dTilesProvider {
|
|
|
96217
96232
|
// Order by most occurances to least
|
|
96218
96233
|
// See https://developers.google.com/maps/documentation/tile/create-renderer#display-attributions
|
|
96219
96234
|
const sortedCopyrights = [...copyrightMap.entries()].sort((a, b) => b[1] - a[1]);
|
|
96220
|
-
|
|
96221
|
-
|
|
96222
|
-
|
|
96235
|
+
const list = document.createElement("ul");
|
|
96236
|
+
for (const [key] of sortedCopyrights) {
|
|
96237
|
+
const item = document.createElement("li");
|
|
96238
|
+
item.textContent = key;
|
|
96239
|
+
list.appendChild(item);
|
|
96240
|
+
}
|
|
96223
96241
|
const iconSrc = document.createElement("img");
|
|
96224
96242
|
iconSrc.src = `${_IModelApp__WEBPACK_IMPORTED_MODULE_8__.IModelApp.publicPath}images/GoogleMaps_Logo_Gray.svg`;
|
|
96225
96243
|
iconSrc.style.padding = "10px 10px 5px 10px";
|
|
@@ -96227,7 +96245,7 @@ class Google3dTilesProvider {
|
|
|
96227
96245
|
iconSrc,
|
|
96228
96246
|
iconWidth: 98,
|
|
96229
96247
|
heading: "Google Photorealistic 3D Tiles",
|
|
96230
|
-
|
|
96248
|
+
noticeLines: ["Data provided by:", list],
|
|
96231
96249
|
}));
|
|
96232
96250
|
}
|
|
96233
96251
|
}
|
|
@@ -116617,7 +116635,7 @@ class GoogleMapsDecorator {
|
|
|
116617
116635
|
const copyrightText = sortedCopyrights.map(([key]) => ` • ${key}`).join("");
|
|
116618
116636
|
// Create and add element, offset to leave space for i.js and Google logos
|
|
116619
116637
|
const elem = document.createElement("div");
|
|
116620
|
-
elem.
|
|
116638
|
+
elem.textContent = copyrightText;
|
|
116621
116639
|
elem.style.color = "white";
|
|
116622
116640
|
elem.style.fontSize = "11px";
|
|
116623
116641
|
elem.style.textWrap = "wrap";
|
|
@@ -153464,6 +153482,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
153464
153482
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
153465
153483
|
/* harmony export */ OrbitGtTileTree: () => (/* binding */ OrbitGtTileTree),
|
|
153466
153484
|
/* harmony export */ OrbitGtTreeReference: () => (/* binding */ OrbitGtTreeReference),
|
|
153485
|
+
/* harmony export */ computeOrthometricVerticalShift: () => (/* binding */ computeOrthometricVerticalShift),
|
|
153467
153486
|
/* harmony export */ createOrbitGtTileTreeReference: () => (/* binding */ createOrbitGtTileTreeReference)
|
|
153468
153487
|
/* harmony export */ });
|
|
153469
153488
|
/* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
|
|
@@ -153471,11 +153490,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
153471
153490
|
/* harmony import */ var _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @itwin/core-geometry */ "../../core/geometry/lib/esm/core-geometry.js");
|
|
153472
153491
|
/* harmony import */ var _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @itwin/core-orbitgt */ "../../core/orbitgt/lib/esm/core-orbitgt.js");
|
|
153473
153492
|
/* harmony import */ var _BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../BackgroundMapGeometry */ "../../core/frontend/lib/esm/BackgroundMapGeometry.js");
|
|
153474
|
-
/* harmony import */ var
|
|
153475
|
-
/* harmony import */ var
|
|
153476
|
-
/* harmony import */ var
|
|
153477
|
-
/* harmony import */ var
|
|
153478
|
-
/* harmony import */ var
|
|
153493
|
+
/* harmony import */ var _common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../common/FrontendLoggerCategory */ "../../core/frontend/lib/esm/common/FrontendLoggerCategory.js");
|
|
153494
|
+
/* harmony import */ var _DisplayStyleState__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../DisplayStyleState */ "../../core/frontend/lib/esm/DisplayStyleState.js");
|
|
153495
|
+
/* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
|
|
153496
|
+
/* harmony import */ var _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../RealityDataSource */ "../../core/frontend/lib/esm/RealityDataSource.js");
|
|
153497
|
+
/* harmony import */ var _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../common/internal/render/MeshPrimitives */ "../../core/frontend/lib/esm/common/internal/render/MeshPrimitives.js");
|
|
153498
|
+
/* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
|
|
153479
153499
|
/*---------------------------------------------------------------------------------------------
|
|
153480
153500
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
153481
153501
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -153493,6 +153513,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
153493
153513
|
|
|
153494
153514
|
|
|
153495
153515
|
|
|
153516
|
+
|
|
153496
153517
|
const scratchRange = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.create();
|
|
153497
153518
|
const scratchWorldFrustum = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Frustum();
|
|
153498
153519
|
function compareSourceKeys(lhs, rhs) {
|
|
@@ -153556,7 +153577,7 @@ class OrbitGtTileTreeParams {
|
|
|
153556
153577
|
id;
|
|
153557
153578
|
modelId;
|
|
153558
153579
|
iModel;
|
|
153559
|
-
get priority() { return
|
|
153580
|
+
get priority() { return _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileLoadPriority.Context; }
|
|
153560
153581
|
constructor(rdSourceKey, iModel, modelId, location) {
|
|
153561
153582
|
this.location = location;
|
|
153562
153583
|
const key = rdSourceKey;
|
|
@@ -153565,10 +153586,10 @@ class OrbitGtTileTreeParams {
|
|
|
153565
153586
|
this.iModel = iModel;
|
|
153566
153587
|
}
|
|
153567
153588
|
}
|
|
153568
|
-
class OrbitGtRootTile extends
|
|
153589
|
+
class OrbitGtRootTile extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.Tile {
|
|
153569
153590
|
_loadChildren(_resolve, _reject) { }
|
|
153570
153591
|
async requestContent(_isCanceled) { return undefined; }
|
|
153571
|
-
get channel() { return
|
|
153592
|
+
get channel() { return _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.channels.getForHttp("itwinjs-orbitgit"); }
|
|
153572
153593
|
async readContent(_data, _system, _isCanceled) { return {}; }
|
|
153573
153594
|
freeMemory() { }
|
|
153574
153595
|
constructor(params, tree) { super(params, tree); }
|
|
@@ -153638,7 +153659,7 @@ class TileSortProjector {
|
|
|
153638
153659
|
coordinate.z = point.z;
|
|
153639
153660
|
}
|
|
153640
153661
|
}
|
|
153641
|
-
class OrbitGtTileGraphic extends
|
|
153662
|
+
class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileUsageMarker {
|
|
153642
153663
|
graphic;
|
|
153643
153664
|
constructor(graphic, viewport, time) {
|
|
153644
153665
|
super();
|
|
@@ -153649,7 +153670,7 @@ class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.Til
|
|
|
153649
153670
|
this.graphic[Symbol.dispose]();
|
|
153650
153671
|
}
|
|
153651
153672
|
}
|
|
153652
|
-
class OrbitGtTileTree extends
|
|
153673
|
+
class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileTree {
|
|
153653
153674
|
_dataManager;
|
|
153654
153675
|
_centerOffset;
|
|
153655
153676
|
_ecefTransform;
|
|
@@ -153665,7 +153686,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153665
153686
|
this._dataManager = _dataManager;
|
|
153666
153687
|
this._centerOffset = _centerOffset;
|
|
153667
153688
|
this._ecefTransform = _ecefTransform;
|
|
153668
|
-
this._layerHandler = new
|
|
153689
|
+
this._layerHandler = new _tile_internal__WEBPACK_IMPORTED_MODULE_10__.LayerTileTreeHandler(this);
|
|
153669
153690
|
this._tileParams = { contentId: "0", range: cloudRange, maximumSize: 256 };
|
|
153670
153691
|
this.rootTile = new OrbitGtRootTile(this._tileParams, this);
|
|
153671
153692
|
}
|
|
@@ -153714,7 +153735,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153714
153735
|
let totalPointCount = 0;
|
|
153715
153736
|
const tileCount = frameData.tilesToRender.size();
|
|
153716
153737
|
// Inform TileAdmin about tiles we are handling ourselves...
|
|
153717
|
-
|
|
153738
|
+
_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.addExternalTilesForUser(args.context.viewport, { requested: frameData.tilesToLoad.size() + (frameData.hasMissingData() ? 1 : 0), selected: tileCount, ready: tileCount });
|
|
153718
153739
|
if (debugBuilder)
|
|
153719
153740
|
debugBuilder.setSymbology(_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ColorDef.red, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ColorDef.red, 1);
|
|
153720
153741
|
let minLevel = 100, maxLevel = -100;
|
|
@@ -153735,8 +153756,8 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153735
153756
|
range.high.addInPlace(this._centerOffset);
|
|
153736
153757
|
const qParams = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QParams3d.fromRange(range, undefined, (tile.points8 != null) ? _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Quantization.rangeScale8 : _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Quantization.rangeScale16);
|
|
153737
153758
|
const featureTable = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureTable(1, this.modelId, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.BatchType.Primary);
|
|
153738
|
-
const features = new
|
|
153739
|
-
const system =
|
|
153759
|
+
const features = new _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_9__.Mesh.Features(featureTable);
|
|
153760
|
+
const system = _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.renderSystem;
|
|
153740
153761
|
const voxelSize = (range.high.x - range.low.x) / 64;
|
|
153741
153762
|
features.add(new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Feature(this.modelId), 1);
|
|
153742
153763
|
const tilePoints = (tile.points8 != null) ? tile.points8.toNativeBuffer() : tile.points16.toNativeBuffer();
|
|
@@ -153763,8 +153784,34 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153763
153784
|
}
|
|
153764
153785
|
args.drawGraphics();
|
|
153765
153786
|
if (frameData.hasMissingData()) {
|
|
153766
|
-
this._dataManager.loadData(frameData).then(() =>
|
|
153787
|
+
this._dataManager.loadData(frameData).then(() => _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.onTileLoad.raiseEvent(this.rootTile)).catch((_err) => undefined);
|
|
153788
|
+
}
|
|
153789
|
+
}
|
|
153790
|
+
}
|
|
153791
|
+
/** Computes the vertical shift, in meters along geodetic up, to correctly place a point cloud whose CRS does not
|
|
153792
|
+
* define a vertical datum, assuming its heights are orthometric (relative to the geoid).
|
|
153793
|
+
*
|
|
153794
|
+
* The shift is the difference between converting the point cloud's origin with its height treated as orthometric
|
|
153795
|
+
* versus ellipsoidal (`heightAsEllipsoidalDbZ`, already computed by the caller). Returns zero if the shift cannot
|
|
153796
|
+
* be computed or the iModel's converter makes no distinction between the two.
|
|
153797
|
+
* Exported strictly for tests.
|
|
153798
|
+
* @internal
|
|
153799
|
+
*/
|
|
153800
|
+
async function computeOrthometricVerticalShift(geoOrigin, heightAsEllipsoidalDbZ, iModel) {
|
|
153801
|
+
const geoidConverter = iModel.noGcsDefined ? undefined : iModel.geoServices.getConverter({ horizontalCRS: { epsg: 4326 }, verticalCRS: { id: "GEOID" } });
|
|
153802
|
+
if (undefined === geoidConverter)
|
|
153803
|
+
return 0;
|
|
153804
|
+
try {
|
|
153805
|
+
const response = await geoidConverter.getIModelCoordinatesFromGeoCoordinates([geoOrigin]);
|
|
153806
|
+
if (response.iModelCoords[0].s !== _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success) {
|
|
153807
|
+
_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__.FrontendLoggerCategory.RealityData, `Failed to compute orthometric height correction for point cloud (status ${response.iModelCoords[0].s}); heights will be treated as ellipsoidal`);
|
|
153808
|
+
return 0;
|
|
153767
153809
|
}
|
|
153810
|
+
return _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p).z - heightAsEllipsoidalDbZ;
|
|
153811
|
+
}
|
|
153812
|
+
catch (err) {
|
|
153813
|
+
_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logError(_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__.FrontendLoggerCategory.RealityData, err);
|
|
153814
|
+
return 0;
|
|
153768
153815
|
}
|
|
153769
153816
|
}
|
|
153770
153817
|
(function (OrbitGtTileTree) {
|
|
@@ -153790,7 +153837,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153790
153837
|
return isValidSASToken(props.sasToken);
|
|
153791
153838
|
}
|
|
153792
153839
|
async function createOrbitGtTileTree(rdSourceKey, iModel, modelId) {
|
|
153793
|
-
const rdSource = await
|
|
153840
|
+
const rdSource = await _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.fromKey(rdSourceKey, iModel.iTwinId);
|
|
153794
153841
|
const isContextShare = rdSourceKey.provider === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.ContextShare;
|
|
153795
153842
|
const isTilestUrl = rdSourceKey.provider === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.TilesetUrl;
|
|
153796
153843
|
let blobStringUrl;
|
|
@@ -153801,7 +153848,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153801
153848
|
const docRootName = realityData.rootDocument;
|
|
153802
153849
|
if (!docRootName)
|
|
153803
153850
|
return undefined;
|
|
153804
|
-
const token = await
|
|
153851
|
+
const token = await _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.getAccessToken();
|
|
153805
153852
|
const blobUrl = await realityData.getBlobUrl(token, docRootName);
|
|
153806
153853
|
blobStringUrl = blobUrl.toString();
|
|
153807
153854
|
}
|
|
@@ -153809,7 +153856,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153809
153856
|
blobStringUrl = rdSourceKey.id;
|
|
153810
153857
|
}
|
|
153811
153858
|
else {
|
|
153812
|
-
const orbitGtBlobProps =
|
|
153859
|
+
const orbitGtBlobProps = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createOrbitGtBlobPropsFromKey(rdSourceKey);
|
|
153813
153860
|
if (orbitGtBlobProps === undefined)
|
|
153814
153861
|
return undefined;
|
|
153815
153862
|
if (!isValidOrbitGtBlobProps(orbitGtBlobProps))
|
|
@@ -153844,7 +153891,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153844
153891
|
const wgs84CRS = "4978";
|
|
153845
153892
|
await _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.ENGINE.prepareForArea(wgs84CRS, new _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.OrbitGtBounds());
|
|
153846
153893
|
const pointCloudToEcef = transformFromOrbitGt(_itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.createTransform(pointCloudCRS, new _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.OrbitGtCoordinate(pointCloudCenter.x, pointCloudCenter.y, pointCloudCenter.z), wgs84CRS));
|
|
153847
|
-
|
|
153894
|
+
let pointCloudCenterToEcef = pointCloudToEcef.multiplyTransformTransform(addCloudCenter);
|
|
153848
153895
|
ecefTransform.setFrom(pointCloudCenterToEcef);
|
|
153849
153896
|
let ecefToDb = iModel.getMapEcefToDb(0);
|
|
153850
153897
|
// In initial publishing version the iModel ecef Transform was used to locate the reality model.
|
|
@@ -153864,7 +153911,21 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153864
153911
|
const geoOrigin = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(cartographicOrigin.longitudeDegrees, cartographicOrigin.latitudeDegrees, cartographicOrigin.height);
|
|
153865
153912
|
const response = await geoConverter.getIModelCoordinatesFromGeoCoordinates([geoOrigin]);
|
|
153866
153913
|
if (response.iModelCoords[0].s === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success) {
|
|
153867
|
-
const
|
|
153914
|
+
const dbOriginFromGcs = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p);
|
|
153915
|
+
// A projected CRS defines no vertical datum, so the point cloud's heights are conventionally orthometric -
|
|
153916
|
+
// but pointCloudToEcef above treated them as ellipsoidal. Correct the placement by the difference.
|
|
153917
|
+
// (A compound CRS also takes this path; that stays correct unless orbitgt gains a geoid model.)
|
|
153918
|
+
if (_itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.ENGINE.isProjectedCRS(pointCloudCRS)) {
|
|
153919
|
+
const verticalShift = await computeOrthometricVerticalShift(geoOrigin, dbOriginFromGcs.z, iModel);
|
|
153920
|
+
if (0 !== verticalShift) {
|
|
153921
|
+
const upVector = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Vector3d.createStartEnd(cartographicOrigin.toEcef(), _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Cartographic.fromRadians({ longitude: cartographicOrigin.longitude, latitude: cartographicOrigin.latitude, height: cartographicOrigin.height + 1 }).toEcef()).normalize();
|
|
153922
|
+
if (undefined !== upVector) {
|
|
153923
|
+
pointCloudCenterToEcef = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Transform.createTranslation(upVector.scale(verticalShift)).multiplyTransformTransform(pointCloudCenterToEcef);
|
|
153924
|
+
ecefTransform.setFrom(pointCloudCenterToEcef);
|
|
153925
|
+
}
|
|
153926
|
+
}
|
|
153927
|
+
}
|
|
153928
|
+
const ecefToDbOrigin = await (0,_BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__.calculateEcefToDbTransformAtLocation)(dbOriginFromGcs, iModel);
|
|
153868
153929
|
if (ecefToDbOrigin)
|
|
153869
153930
|
ecefToDb = ecefToDbOrigin;
|
|
153870
153931
|
}
|
|
@@ -153884,7 +153945,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
|
|
|
153884
153945
|
/** Supplies a reality data [[TileTree]] from a URL. May be associated with a persistent [[GeometricModelState]], or attached at run-time via a [[ContextOrbitGtState]].
|
|
153885
153946
|
* Exported strictly for tests.
|
|
153886
153947
|
*/
|
|
153887
|
-
class OrbitGtTreeReference extends
|
|
153948
|
+
class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.RealityModelTileTree.Reference {
|
|
153888
153949
|
treeOwner;
|
|
153889
153950
|
_rdSourceKey;
|
|
153890
153951
|
_modelId;
|
|
@@ -153897,15 +153958,15 @@ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.R
|
|
|
153897
153958
|
this._rdSourceKey = props.rdSourceKey;
|
|
153898
153959
|
}
|
|
153899
153960
|
else if (props.orbitGtBlob) {
|
|
153900
|
-
this._rdSourceKey =
|
|
153961
|
+
this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createKeyFromOrbitGtBlobProps(props.orbitGtBlob);
|
|
153901
153962
|
}
|
|
153902
153963
|
else {
|
|
153903
153964
|
// TODO: Maybe we should throw an exception
|
|
153904
|
-
this._rdSourceKey =
|
|
153965
|
+
this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createKeyFromBlobUrl("", _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.OrbitGtBlob, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataFormat.OPC);
|
|
153905
153966
|
}
|
|
153906
153967
|
// ###TODO find compatible model Id
|
|
153907
153968
|
let modelId = props.modelId;
|
|
153908
|
-
if (undefined === modelId && this._source instanceof
|
|
153969
|
+
if (undefined === modelId && this._source instanceof _DisplayStyleState__WEBPACK_IMPORTED_MODULE_6__.DisplayStyleState)
|
|
153909
153970
|
modelId = orbitGtTreeSupplier.findCompatibleContextRealityModelId(this._rdSourceKey, this._source);
|
|
153910
153971
|
this._modelId = modelId ?? props.iModel.transientIds.getNext();
|
|
153911
153972
|
const ogtTreeId = { rdSourceKey: this._rdSourceKey, modelId: this.modelId };
|
|
@@ -153920,11 +153981,15 @@ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.R
|
|
|
153920
153981
|
if (undefined === tree || hit.iModel !== tree.iModel)
|
|
153921
153982
|
return undefined;
|
|
153922
153983
|
const strings = [];
|
|
153923
|
-
strings.push(
|
|
153984
|
+
strings.push(_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.localization.getLocalizedString("iModelJs:RealityModelTypes.OrbitGTPointCloud"));
|
|
153924
153985
|
if (this._name)
|
|
153925
|
-
strings.push(`${
|
|
153986
|
+
strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.localization.getLocalizedString("iModelJs:TooltipInfo.Name")} ${this._name}`);
|
|
153926
153987
|
const div = document.createElement("div");
|
|
153927
|
-
|
|
153988
|
+
strings.forEach((str, index) => {
|
|
153989
|
+
if (index > 0)
|
|
153990
|
+
div.appendChild(document.createElement("br"));
|
|
153991
|
+
div.appendChild(document.createTextNode(str));
|
|
153992
|
+
});
|
|
153928
153993
|
return div;
|
|
153929
153994
|
}
|
|
153930
153995
|
}
|
|
@@ -155688,7 +155753,11 @@ class RealityTreeReference extends RealityModelTileTree.Reference {
|
|
|
155688
155753
|
if (-1 === key.indexOf("#")) // Avoid internal cesium
|
|
155689
155754
|
strings.push(`${key}: ${JSON.stringify(batch[key])}`);
|
|
155690
155755
|
const div = document.createElement("div");
|
|
155691
|
-
|
|
155756
|
+
strings.forEach((str, index) => {
|
|
155757
|
+
if (index > 0)
|
|
155758
|
+
div.appendChild(document.createElement("br"));
|
|
155759
|
+
div.appendChild(document.createTextNode(str));
|
|
155760
|
+
});
|
|
155692
155761
|
return div;
|
|
155693
155762
|
}
|
|
155694
155763
|
/** @deprecated in 5.0 - might be removed in next major version. Use [addAttributions] instead. */
|
|
@@ -156876,7 +156945,21 @@ class ArcGisUtilities {
|
|
|
156876
156945
|
*/
|
|
156877
156946
|
static async validateSource(args) {
|
|
156878
156947
|
const { source, ignoreCache, capabilitiesFilter } = args;
|
|
156879
|
-
|
|
156948
|
+
let metadata;
|
|
156949
|
+
try {
|
|
156950
|
+
metadata = await this.getServiceJson({ url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache });
|
|
156951
|
+
}
|
|
156952
|
+
catch (err) {
|
|
156953
|
+
if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError) {
|
|
156954
|
+
let blockedOrigin;
|
|
156955
|
+
try {
|
|
156956
|
+
blockedOrigin = new URL(err.url).origin;
|
|
156957
|
+
}
|
|
156958
|
+
catch { /* non-hierarchical URL */ }
|
|
156959
|
+
return { status: _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
|
|
156960
|
+
}
|
|
156961
|
+
throw err;
|
|
156962
|
+
}
|
|
156880
156963
|
const json = metadata?.content;
|
|
156881
156964
|
if (json === undefined) {
|
|
156882
156965
|
return { status: _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerSourceStatus.InvalidUrl };
|
|
@@ -156939,6 +157022,9 @@ class ArcGisUtilities {
|
|
|
156939
157022
|
* @param password Password to use for legacy token based security
|
|
156940
157023
|
* @param ignoreCache Flag to skip cache lookup (i.e. force a new server request)
|
|
156941
157024
|
* @param requireToken Flag to indicate if a token is required
|
|
157025
|
+
* @throws [[MapLayerUntrustedOriginError]] if an NTLM/Negotiate challenge could not be answered because
|
|
157026
|
+
* the URL's origin is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]);
|
|
157027
|
+
* all other errors are caught and reported by returning `undefined`.
|
|
156942
157028
|
*/
|
|
156943
157029
|
static async getServiceJson(args) {
|
|
156944
157030
|
const { url, formatId, userName, password, queryParams, ignoreCache, requireToken } = args;
|
|
@@ -156974,8 +157060,17 @@ class ArcGisUtilities {
|
|
|
156974
157060
|
}
|
|
156975
157061
|
let response = await fetch(tmpUrl, { method: "GET" });
|
|
156976
157062
|
if (response.status === 401 && !requireToken && (0,_request_utils__WEBPACK_IMPORTED_MODULE_3__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
|
|
156977
|
-
//
|
|
156978
|
-
|
|
157063
|
+
// fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
|
|
157064
|
+
const challengedUrl = response.url || tmpUrl.toString();
|
|
157065
|
+
if (!_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(challengedUrl))
|
|
157066
|
+
throw new _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError(challengedUrl);
|
|
157067
|
+
_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(challengedUrl);
|
|
157068
|
+
// We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication).
|
|
157069
|
+
response = await fetch(challengedUrl, {
|
|
157070
|
+
method: "GET",
|
|
157071
|
+
credentials: "include",
|
|
157072
|
+
redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
|
|
157073
|
+
});
|
|
156979
157074
|
}
|
|
156980
157075
|
// Append security token when corresponding error code is returned by ArcGIS service
|
|
156981
157076
|
let errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);
|
|
@@ -156997,8 +157092,10 @@ class ArcGisUtilities {
|
|
|
156997
157092
|
ArcGisUtilities._serviceCache.set(url, (errorCode === undefined ? info : undefined));
|
|
156998
157093
|
return info; // Always return json, even though it contains an error code.
|
|
156999
157094
|
}
|
|
157000
|
-
catch {
|
|
157095
|
+
catch (err) {
|
|
157001
157096
|
ArcGisUtilities._serviceCache.set(url, undefined);
|
|
157097
|
+
if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError)
|
|
157098
|
+
throw err; // propagate so callers can report the blocked origin
|
|
157002
157099
|
return undefined;
|
|
157003
157100
|
}
|
|
157004
157101
|
}
|
|
@@ -157160,7 +157257,9 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
|
|
|
157160
157257
|
try {
|
|
157161
157258
|
metadata = await _tile_internal__WEBPACK_IMPORTED_MODULE_0__.ArcGisUtilities.getServiceJson({ url: this._settings.url, formatId: this._settings.formatId, userName: this._settings.userName, password: this._settings.password, queryParams: this._settings.collectQueryParams() });
|
|
157162
157259
|
}
|
|
157163
|
-
catch {
|
|
157260
|
+
catch (err) {
|
|
157261
|
+
if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError)
|
|
157262
|
+
this.reportBlockedOrigin(err.url);
|
|
157164
157263
|
}
|
|
157165
157264
|
if (metadata && metadata.accessTokenRequired) {
|
|
157166
157265
|
const accessClient = _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.mapLayerFormatRegistry.getAccessClient(this._settings.formatId);
|
|
@@ -157208,12 +157307,32 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
|
|
|
157208
157307
|
await this._firstRequestPromise;
|
|
157209
157308
|
let response;
|
|
157210
157309
|
try {
|
|
157211
|
-
|
|
157310
|
+
const requestUrl = urlObj.toString();
|
|
157311
|
+
const includeCredentials = this.includeUserCredentials(requestUrl);
|
|
157312
|
+
response = await fetch(urlObj, {
|
|
157313
|
+
...options,
|
|
157314
|
+
credentials: includeCredentials ? "include" : undefined,
|
|
157315
|
+
redirect: includeCredentials ? this.credentialedRedirect : options?.redirect,
|
|
157316
|
+
});
|
|
157317
|
+
if (includeCredentials)
|
|
157318
|
+
this.checkCredentialedRedirect(requestUrl, response);
|
|
157212
157319
|
if (response.status === 401 && !this._lastAccessToken && (0,_request_utils__WEBPACK_IMPORTED_MODULE_3__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
|
|
157213
|
-
//
|
|
157214
|
-
|
|
157215
|
-
if (
|
|
157216
|
-
|
|
157320
|
+
// fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
|
|
157321
|
+
const challengedUrl = response.url || requestUrl;
|
|
157322
|
+
if (this.isSsoAllowed(challengedUrl)) {
|
|
157323
|
+
// We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication).
|
|
157324
|
+
this.logUntrustedOriginUse(challengedUrl);
|
|
157325
|
+
response = await fetch(challengedUrl, {
|
|
157326
|
+
...options,
|
|
157327
|
+
credentials: "include",
|
|
157328
|
+
redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
|
|
157329
|
+
});
|
|
157330
|
+
if (response.status === 200) {
|
|
157331
|
+
this.recordSsoSucceeded(challengedUrl); // avoid going through 401 challenges over and over for this origin
|
|
157332
|
+
}
|
|
157333
|
+
}
|
|
157334
|
+
else {
|
|
157335
|
+
this.reportBlockedOrigin(challengedUrl);
|
|
157217
157336
|
}
|
|
157218
157337
|
}
|
|
157219
157338
|
if ((this._lastAccessToken && response.status === 400)
|
|
@@ -157426,8 +157545,12 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
|
|
|
157426
157545
|
}
|
|
157427
157546
|
async initialize() {
|
|
157428
157547
|
const metadata = await this.getServiceJson();
|
|
157429
|
-
if (metadata?.content === undefined)
|
|
157548
|
+
if (metadata?.content === undefined) {
|
|
157549
|
+
// By returning (i.e., not throwing), we ensure the tile tree gets created and the current provider is preserved to report status.
|
|
157550
|
+
if (this.status === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerImageryProviderStatus.UntrustedOrigin)
|
|
157551
|
+
return;
|
|
157430
157552
|
throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_0__.ServerError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_5__.IModelStatus.ValidationFailed, "");
|
|
157553
|
+
}
|
|
157431
157554
|
const json = metadata.content;
|
|
157432
157555
|
if (json?.error?.code === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.ArcGisErrorCode.TokenRequired
|
|
157433
157556
|
|| json?.error?.code === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.ArcGisErrorCode.InvalidToken
|
|
@@ -157512,7 +157635,7 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
|
|
|
157512
157635
|
addLogoCards(cards) {
|
|
157513
157636
|
if (!cards.dataset.arcGisLogoCard) {
|
|
157514
157637
|
cards.dataset.arcGisLogoCard = "true";
|
|
157515
|
-
cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.makeLogoCard({ heading: "ArcGIS",
|
|
157638
|
+
cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.makeLogoCard({ heading: "ArcGIS", noticeLines: [this._copyrightText] }));
|
|
157516
157639
|
}
|
|
157517
157640
|
}
|
|
157518
157641
|
async addAttributions(cards, _vp) {
|
|
@@ -157553,7 +157676,7 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
|
|
|
157553
157676
|
if (json && Array.isArray(json.results)) {
|
|
157554
157677
|
for (const result of json.results) {
|
|
157555
157678
|
if (result.attributes !== undefined && result.attributes[result.displayFieldName] !== undefined) {
|
|
157556
|
-
const thisString = `${result.displayFieldName}: ${result.attributes[result.displayFieldName]}`;
|
|
157679
|
+
const thisString = `${(0,_tile_internal__WEBPACK_IMPORTED_MODULE_2__.escapeHtml)(String(result.displayFieldName))}: ${(0,_tile_internal__WEBPACK_IMPORTED_MODULE_2__.escapeHtml)(String(result.attributes[result.displayFieldName]))}`;
|
|
157557
157680
|
if (!stringSet.has(thisString)) {
|
|
157558
157681
|
strings.push(thisString);
|
|
157559
157682
|
stringSet.add(thisString);
|
|
@@ -157869,13 +157992,7 @@ class BingMapsImageryLayerProvider extends _tile_internal__WEBPACK_IMPORTED_MODU
|
|
|
157869
157992
|
const copyrights = [];
|
|
157870
157993
|
for (const match of matchingAttributions)
|
|
157871
157994
|
copyrights.push(match.copyrightMessage);
|
|
157872
|
-
|
|
157873
|
-
for (let i = 0; i < copyrights.length; ++i) {
|
|
157874
|
-
if (i > 0)
|
|
157875
|
-
copyrightMsg += "<br>";
|
|
157876
|
-
copyrightMsg += copyrights[i];
|
|
157877
|
-
}
|
|
157878
|
-
cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.makeLogoCard({ iconSrc: `${_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.publicPath}images/bing.svg`, heading: "Microsoft Bing", notice: copyrightMsg }));
|
|
157995
|
+
cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.makeLogoCard({ iconSrc: `${_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.publicPath}images/bing.svg`, heading: "Microsoft Bing", noticeLines: copyrights }));
|
|
157879
157996
|
}
|
|
157880
157997
|
async addAttributions(cards, vp) {
|
|
157881
157998
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
@@ -158484,7 +158601,10 @@ class WmsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE
|
|
|
158484
158601
|
// Don't throw error if unauthorized status:
|
|
158485
158602
|
// We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials.
|
|
158486
158603
|
// When credentials will be provided, a new provider will be created, and initialization should be fine.
|
|
158487
|
-
if (error
|
|
158604
|
+
if (error instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError) {
|
|
158605
|
+
this.reportBlockedOrigin(error.url);
|
|
158606
|
+
}
|
|
158607
|
+
else if (error?.status === 401) {
|
|
158488
158608
|
this.setStatus(_tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerImageryProviderStatus.RequireAuth);
|
|
158489
158609
|
}
|
|
158490
158610
|
else {
|
|
@@ -158646,7 +158766,8 @@ class WmtsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODUL
|
|
|
158646
158766
|
}
|
|
158647
158767
|
async initialize() {
|
|
158648
158768
|
try {
|
|
158649
|
-
this.
|
|
158769
|
+
const credentials = (this._settings.userName && this._settings.password ? { user: this._settings.userName, password: this._settings.password } : undefined);
|
|
158770
|
+
this._capabilities = await _tile_internal__WEBPACK_IMPORTED_MODULE_2__.WmtsCapabilities.create(this._baseUrl, credentials);
|
|
158650
158771
|
this.initPreferredTileMatrixSet();
|
|
158651
158772
|
this.initPreferredStyle();
|
|
158652
158773
|
this.initDisplayedLayer();
|
|
@@ -158659,7 +158780,10 @@ class WmtsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODUL
|
|
|
158659
158780
|
// Don't throw error if unauthorized status:
|
|
158660
158781
|
// We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials.
|
|
158661
158782
|
// When credentials will be provided, a new provider will be created, and initialization should be fine.
|
|
158662
|
-
if (error
|
|
158783
|
+
if (error instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerUntrustedOriginError) {
|
|
158784
|
+
this.reportBlockedOrigin(error.url);
|
|
158785
|
+
}
|
|
158786
|
+
else if (error?.status === 401) {
|
|
158663
158787
|
this.setStatus(_tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerImageryProviderStatus.RequireAuth);
|
|
158664
158788
|
}
|
|
158665
158789
|
else {
|
|
@@ -159470,14 +159594,18 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
159470
159594
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
159471
159595
|
/* harmony export */ WmsUtilities: () => (/* binding */ WmsUtilities)
|
|
159472
159596
|
/* harmony export */ });
|
|
159473
|
-
/* harmony import */ var
|
|
159474
|
-
/* harmony import */ var
|
|
159597
|
+
/* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
|
|
159598
|
+
/* harmony import */ var _request_Request__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../request/Request */ "../../core/frontend/lib/esm/request/Request.js");
|
|
159599
|
+
/* harmony import */ var _request_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../request/utils */ "../../core/frontend/lib/esm/request/utils.js");
|
|
159600
|
+
/* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
|
|
159475
159601
|
/*---------------------------------------------------------------------------------------------
|
|
159476
159602
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
159477
159603
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
159478
159604
|
*--------------------------------------------------------------------------------------------*/
|
|
159479
159605
|
|
|
159480
159606
|
|
|
159607
|
+
|
|
159608
|
+
|
|
159481
159609
|
/** @packageDocumentation
|
|
159482
159610
|
* @module Tiles
|
|
159483
159611
|
*/
|
|
@@ -159494,16 +159622,35 @@ class WmsUtilities {
|
|
|
159494
159622
|
static async fetchXml(url, credentials) {
|
|
159495
159623
|
let headers;
|
|
159496
159624
|
if (credentials && credentials.user && credentials.password) {
|
|
159497
|
-
|
|
159498
|
-
|
|
159625
|
+
// Basic credentials are considered settings-derived credentials for this source. When the registry is
|
|
159626
|
+
// enforcing trusted origins, the source URL itself is the only implicitly trusted origin for basic auth;
|
|
159627
|
+
// opaque/custom-protocol URLs have no network origin and must therefore be treated as untrusted.
|
|
159628
|
+
const allowBasicAuth = !_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins
|
|
159629
|
+
|| _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, url);
|
|
159630
|
+
if (allowBasicAuth) {
|
|
159631
|
+
headers = new Headers();
|
|
159632
|
+
(0,_request_utils__WEBPACK_IMPORTED_MODULE_2__.setBasicAuthorization)(headers, credentials);
|
|
159633
|
+
}
|
|
159499
159634
|
}
|
|
159500
159635
|
let response = await fetch(url, { method: "GET", headers });
|
|
159501
|
-
if (!credentials && response.status === 401
|
|
159502
|
-
|
|
159503
|
-
|
|
159636
|
+
if (!headers && credentials && credentials.user && credentials.password && (response.status === 401 || response.status === 403)) {
|
|
159637
|
+
throw new _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError(url);
|
|
159638
|
+
}
|
|
159639
|
+
if (!credentials && response.status === 401 && (0,_request_utils__WEBPACK_IMPORTED_MODULE_2__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
|
|
159640
|
+
// fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
|
|
159641
|
+
const challengedUrl = response.url || url;
|
|
159642
|
+
if (!_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(challengedUrl))
|
|
159643
|
+
throw new _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError(challengedUrl);
|
|
159644
|
+
_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(challengedUrl);
|
|
159645
|
+
// We got a http 401 challenge, lets try SSO (i.e. Windows Authentication).
|
|
159646
|
+
response = await fetch(challengedUrl, {
|
|
159647
|
+
method: "GET",
|
|
159648
|
+
credentials: "include",
|
|
159649
|
+
redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
|
|
159650
|
+
});
|
|
159504
159651
|
}
|
|
159505
159652
|
if (response.status !== 200)
|
|
159506
|
-
throw new
|
|
159653
|
+
throw new _request_Request__WEBPACK_IMPORTED_MODULE_1__.HttpResponseError(response.status, await response.text());
|
|
159507
159654
|
return response.text();
|
|
159508
159655
|
}
|
|
159509
159656
|
}
|
|
@@ -171917,6 +172064,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
171917
172064
|
/* harmony export */ MapLayerSourceStatus: () => (/* reexport safe */ _map_MapLayerSources__WEBPACK_IMPORTED_MODULE_86__.MapLayerSourceStatus),
|
|
171918
172065
|
/* harmony export */ MapLayerSources: () => (/* reexport safe */ _map_MapLayerSources__WEBPACK_IMPORTED_MODULE_86__.MapLayerSources),
|
|
171919
172066
|
/* harmony export */ MapLayerTileTreeReference: () => (/* reexport safe */ _map_MapLayerTileTreeReference__WEBPACK_IMPORTED_MODULE_64__.MapLayerTileTreeReference),
|
|
172067
|
+
/* harmony export */ MapLayerUntrustedOriginError: () => (/* reexport safe */ _map_MapLayerFormatRegistry__WEBPACK_IMPORTED_MODULE_42__.MapLayerUntrustedOriginError),
|
|
171920
172068
|
/* harmony export */ MapTile: () => (/* reexport safe */ _map_MapTile__WEBPACK_IMPORTED_MODULE_70__.MapTile),
|
|
171921
172069
|
/* harmony export */ MapTileLoader: () => (/* reexport safe */ _internal_tile_map_MapTileLoader__WEBPACK_IMPORTED_MODULE_72__.MapTileLoader),
|
|
171922
172070
|
/* harmony export */ MapTileProjection: () => (/* reexport safe */ _map_MapTile__WEBPACK_IMPORTED_MODULE_70__.MapTileProjection),
|
|
@@ -171996,6 +172144,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
171996
172144
|
/* harmony export */ collectMaskRefs: () => (/* reexport safe */ _internal_tile_PrimaryTileTree__WEBPACK_IMPORTED_MODULE_82__.collectMaskRefs),
|
|
171997
172145
|
/* harmony export */ compareMapLayer: () => (/* reexport safe */ _internal_render_webgl_MapLayerParams__WEBPACK_IMPORTED_MODULE_94__.compareMapLayer),
|
|
171998
172146
|
/* harmony export */ computeCesiumTokenTimeoutInterval: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.computeCesiumTokenTimeoutInterval),
|
|
172147
|
+
/* harmony export */ computeOrthometricVerticalShift: () => (/* reexport safe */ _internal_tile_OrbitGtTileTree__WEBPACK_IMPORTED_MODULE_84__.computeOrthometricVerticalShift),
|
|
171999
172148
|
/* harmony export */ createClassifierTileTreeReference: () => (/* reexport safe */ _internal_tile_ClassifierTileTree__WEBPACK_IMPORTED_MODULE_83__.createClassifierTileTreeReference),
|
|
172000
172149
|
/* harmony export */ createDefaultViewFlagOverrides: () => (/* reexport safe */ _internal_tile_ViewFlagOverrides__WEBPACK_IMPORTED_MODULE_0__.createDefaultViewFlagOverrides),
|
|
172001
172150
|
/* harmony export */ createGraphicFromDescription: () => (/* reexport safe */ _internal_tile_ImdlGraphicsCreator__WEBPACK_IMPORTED_MODULE_37__.createGraphicFromDescription),
|
|
@@ -172012,6 +172161,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
172012
172161
|
/* harmony export */ decodeMeshoptBuffer: () => (/* reexport safe */ _internal_tile_MeshoptCompression__WEBPACK_IMPORTED_MODULE_93__.decodeMeshoptBuffer),
|
|
172013
172162
|
/* harmony export */ deflateCoordinates: () => (/* reexport safe */ _internal_tile_map_ImageryProviders_CoordinatesUtils__WEBPACK_IMPORTED_MODULE_47__.deflateCoordinates),
|
|
172014
172163
|
/* harmony export */ disposeTileTreesForGeometricModels: () => (/* reexport safe */ _internal_tile_PrimaryTileTree__WEBPACK_IMPORTED_MODULE_82__.disposeTileTreesForGeometricModels),
|
|
172164
|
+
/* harmony export */ escapeHtml: () => (/* reexport safe */ _map_MapLayerImageryProvider__WEBPACK_IMPORTED_MODULE_49__.escapeHtml),
|
|
172015
172165
|
/* harmony export */ getCesiumAccessClient: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAccessClient),
|
|
172016
172166
|
/* harmony export */ getCesiumAccessTokenAndEndpointUrl: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAccessTokenAndEndpointUrl),
|
|
172017
172167
|
/* harmony export */ getCesiumAssetUrl: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAssetUrl),
|
|
@@ -172031,7 +172181,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
172031
172181
|
/* harmony export */ readImdlContent: () => (/* reexport safe */ _ImdlReader__WEBPACK_IMPORTED_MODULE_35__.readImdlContent),
|
|
172032
172182
|
/* harmony export */ readPntsColors: () => (/* reexport safe */ _internal_tile_PntsReader__WEBPACK_IMPORTED_MODULE_76__.readPntsColors),
|
|
172033
172183
|
/* harmony export */ readPointCloudTileContent: () => (/* reexport safe */ _internal_tile_PntsReader__WEBPACK_IMPORTED_MODULE_76__.readPointCloudTileContent),
|
|
172034
|
-
/* harmony export */ tileTreeReferenceFromRenderGraphic: () => (/* reexport safe */ _RenderGraphicTileTree__WEBPACK_IMPORTED_MODULE_78__.tileTreeReferenceFromRenderGraphic)
|
|
172184
|
+
/* harmony export */ tileTreeReferenceFromRenderGraphic: () => (/* reexport safe */ _RenderGraphicTileTree__WEBPACK_IMPORTED_MODULE_78__.tileTreeReferenceFromRenderGraphic),
|
|
172185
|
+
/* harmony export */ tryGetOrigin: () => (/* reexport safe */ _map_MapLayerImageryProvider__WEBPACK_IMPORTED_MODULE_49__.tryGetOrigin)
|
|
172035
172186
|
/* harmony export */ });
|
|
172036
172187
|
/* harmony import */ var _internal_tile_ViewFlagOverrides__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal/tile/ViewFlagOverrides */ "../../core/frontend/lib/esm/internal/tile/ViewFlagOverrides.js");
|
|
172037
172188
|
/* harmony import */ var _map_MapCartoRectangle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./map/MapCartoRectangle */ "../../core/frontend/lib/esm/tile/map/MapCartoRectangle.js");
|
|
@@ -173730,7 +173881,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
173730
173881
|
__webpack_require__.r(__webpack_exports__);
|
|
173731
173882
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
173732
173883
|
/* harmony export */ MapLayerFormat: () => (/* binding */ MapLayerFormat),
|
|
173733
|
-
/* harmony export */ MapLayerFormatRegistry: () => (/* binding */ MapLayerFormatRegistry)
|
|
173884
|
+
/* harmony export */ MapLayerFormatRegistry: () => (/* binding */ MapLayerFormatRegistry),
|
|
173885
|
+
/* harmony export */ MapLayerUntrustedOriginError: () => (/* binding */ MapLayerUntrustedOriginError)
|
|
173734
173886
|
/* harmony export */ });
|
|
173735
173887
|
/* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
|
|
173736
173888
|
/* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
|
|
@@ -173745,7 +173897,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
173745
173897
|
|
|
173746
173898
|
|
|
173747
173899
|
|
|
173748
|
-
const loggerCategory = "
|
|
173900
|
+
const loggerCategory = "MapLayerFormatRegistry";
|
|
173749
173901
|
/**
|
|
173750
173902
|
* Class representing a map-layer format.
|
|
173751
173903
|
* Each format has it's unique 'formatId' string, used to uniquely identify a format in the [[MapLayerFormatRegistry]].
|
|
@@ -173794,16 +173946,127 @@ class MapLayerFormat {
|
|
|
173794
173946
|
return undefined;
|
|
173795
173947
|
}
|
|
173796
173948
|
}
|
|
173949
|
+
/** Error thrown when an NTLM or Negotiate http 401 challenge could not be answered because the request
|
|
173950
|
+
* URL's origin is not listed in [[MapLayerFormatRegistry.trustedCredentialsOrigins]]
|
|
173951
|
+
* (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
|
|
173952
|
+
* Thrown by the static map-layer utilities (e.g. capabilities / service-metadata fetches) that have no
|
|
173953
|
+
* provider instance on which to report the blocked origin; callers convert it to
|
|
173954
|
+
* [[MapLayerImageryProviderStatus.UntrustedOrigin]] (provider initialization) or
|
|
173955
|
+
* [[MapLayerSourceStatus.UntrustedOrigin]] (source validation).
|
|
173956
|
+
* @internal
|
|
173957
|
+
*/
|
|
173958
|
+
class MapLayerUntrustedOriginError extends Error {
|
|
173959
|
+
/** The URL of the request whose authentication challenge was left unanswered. */
|
|
173960
|
+
url;
|
|
173961
|
+
constructor(url) {
|
|
173962
|
+
super(`Authentication blocked: origin of '${url}' is not listed in MapLayerFormatRegistry.trustedCredentialsOrigins`);
|
|
173963
|
+
this.url = url;
|
|
173964
|
+
}
|
|
173965
|
+
}
|
|
173797
173966
|
/**
|
|
173798
173967
|
* A registry of MapLayerFormats identified by their unique format IDs. The registry can be accessed via [[IModelApp.mapLayerFormatRegistry]].
|
|
173799
173968
|
* @public
|
|
173800
173969
|
*/
|
|
173801
173970
|
class MapLayerFormatRegistry {
|
|
173802
173971
|
_configOptions;
|
|
173972
|
+
_trustedCredentialsOrigins = [];
|
|
173973
|
+
/** Opt-in enforcement of origin restrictions on map-layer credentials.
|
|
173974
|
+
* When enabled, map layer providers:
|
|
173975
|
+
* - attach the basic-auth credentials stored in the layer settings only to requests targeting the origin
|
|
173976
|
+
* of the layer's settings URL or an origin listed in [[trustedCredentialsOrigins]];
|
|
173977
|
+
* - retry a request with browser credentials included (i.e. SSO / Windows Authentication) after an NTLM
|
|
173978
|
+
* or Negotiate http 401 challenge only for origins explicitly listed in [[trustedCredentialsOrigins]]
|
|
173979
|
+
* (the settings-URL origin is NOT implicitly trusted for SSO, since map-layer URLs may originate from
|
|
173980
|
+
* untrusted user input while SSO shares the user's ambient identity).
|
|
173981
|
+
* Default is false, preserving the legacy behavior of sending credentials to any request URL.
|
|
173982
|
+
* @beta
|
|
173983
|
+
*/
|
|
173984
|
+
restrictCredentialsToTrustedOrigins = false;
|
|
173803
173985
|
constructor(opts) {
|
|
173804
173986
|
this._configOptions = opts ?? {};
|
|
173805
173987
|
_internal__WEBPACK_IMPORTED_MODULE_2__.internalMapLayerImageryFormats.forEach((format) => this.register(format));
|
|
173806
173988
|
}
|
|
173989
|
+
/** Origins (e.g. "https://tiles.example.com") to which map layer providers may send credentials —
|
|
173990
|
+
* both the basic-auth credentials stored in the layer settings and browser credentials for
|
|
173991
|
+
* SSO (i.e. Windows Authentication) retries after an NTLM or Negotiate http 401 challenge.
|
|
173992
|
+
* Only enforced when [[restrictCredentialsToTrustedOrigins]] is enabled.
|
|
173993
|
+
* For basic-auth, the origin of each map layer's settings URL is always implicitly trusted; for SSO,
|
|
173994
|
+
* origins must be explicitly listed here.
|
|
173995
|
+
* Entries are normalized to their origin (scheme + host + port); only `http:` and `https:` URLs are accepted,
|
|
173996
|
+
* and any other entry is ignored and logged. Opaque schemes such as `file:`, `data:`, `about:` and custom
|
|
173997
|
+
* Electron protocols are rejected because they all share the same serialized origin, so trusting one would
|
|
173998
|
+
* trust every other.
|
|
173999
|
+
* @beta
|
|
174000
|
+
*/
|
|
174001
|
+
get trustedCredentialsOrigins() {
|
|
174002
|
+
return this._trustedCredentialsOrigins;
|
|
174003
|
+
}
|
|
174004
|
+
set trustedCredentialsOrigins(origins) {
|
|
174005
|
+
const normalized = [];
|
|
174006
|
+
for (const entry of origins) {
|
|
174007
|
+
const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(entry);
|
|
174008
|
+
if (origin !== undefined)
|
|
174009
|
+
normalized.push(origin);
|
|
174010
|
+
else
|
|
174011
|
+
_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(loggerCategory, `trustedCredentialsOrigins: ignoring '${entry}'; entries must be http or https URLs.`);
|
|
174012
|
+
}
|
|
174013
|
+
this._trustedCredentialsOrigins = normalized;
|
|
174014
|
+
}
|
|
174015
|
+
/** Returns true if a request to the given URL may be retried with browser credentials included
|
|
174016
|
+
* (i.e. SSO / Windows Authentication) after an NTLM or Negotiate http 401 challenge.
|
|
174017
|
+
* Always true unless [[restrictCredentialsToTrustedOrigins]] is enabled (opt-in).
|
|
174018
|
+
* When enabled, the URL's origin must be explicitly listed in [[trustedCredentialsOrigins]];
|
|
174019
|
+
* unlike basic-auth, the settings-URL origin is NOT implicitly trusted because SSO shares the user's
|
|
174020
|
+
* ambient identity, and map-layer URLs may originate from untrusted user input.
|
|
174021
|
+
* @internal
|
|
174022
|
+
*/
|
|
174023
|
+
isSsoAllowed(url) {
|
|
174024
|
+
if (!this.restrictCredentialsToTrustedOrigins)
|
|
174025
|
+
return true;
|
|
174026
|
+
const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url);
|
|
174027
|
+
// Entries are normalized to their origin by the [[trustedCredentialsOrigins]] setter.
|
|
174028
|
+
return origin !== undefined && this._trustedCredentialsOrigins.includes(origin);
|
|
174029
|
+
}
|
|
174030
|
+
/** Returns true if the basic-auth credentials belonging to a map-layer source or settings URL may be
|
|
174031
|
+
* attached to a request to the given URL. Always true unless [[restrictCredentialsToTrustedOrigins]]
|
|
174032
|
+
* is enabled (opt-in). When enabled, the origin of `settingsUrl` is implicitly trusted (the credentials
|
|
174033
|
+
* belong to that server); any other origin must be listed in [[trustedCredentialsOrigins]].
|
|
174034
|
+
* @internal
|
|
174035
|
+
*/
|
|
174036
|
+
isCredentialsSharingAllowed(url, settingsUrl) {
|
|
174037
|
+
if (!this.restrictCredentialsToTrustedOrigins)
|
|
174038
|
+
return true;
|
|
174039
|
+
const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url);
|
|
174040
|
+
if (origin === undefined)
|
|
174041
|
+
return false;
|
|
174042
|
+
if (origin === (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(settingsUrl))
|
|
174043
|
+
return true;
|
|
174044
|
+
// Entries are normalized to their origin by the [[trustedCredentialsOrigins]] setter.
|
|
174045
|
+
return this._trustedCredentialsOrigins.includes(origin);
|
|
174046
|
+
}
|
|
174047
|
+
/** Origins for which a "credentials sent to untrusted origin" warning was already logged;
|
|
174048
|
+
* used to log the discovery warning only once per origin.
|
|
174049
|
+
*/
|
|
174050
|
+
_untrustedUseLogged = new Set();
|
|
174051
|
+
/** Logs a warning (once per origin) when credentials are sent to an origin that would be blocked
|
|
174052
|
+
* if [[restrictCredentialsToTrustedOrigins]] were enabled.
|
|
174053
|
+
* Helps applications discover the origins they need to whitelist before opting in to the restriction.
|
|
174054
|
+
* If `settingsUrl` is supplied, requests sharing its origin are not logged, since that origin is
|
|
174055
|
+
* implicitly trusted for basic-auth.
|
|
174056
|
+
* @internal
|
|
174057
|
+
*/
|
|
174058
|
+
logUntrustedOriginUse(url, settingsUrl) {
|
|
174059
|
+
if (this.restrictCredentialsToTrustedOrigins)
|
|
174060
|
+
return; // restriction active; nothing to preview
|
|
174061
|
+
const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url) ?? url;
|
|
174062
|
+
if (settingsUrl !== undefined && origin === (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(settingsUrl))
|
|
174063
|
+
return; // implicitly trusted for basic-auth
|
|
174064
|
+
if (this._untrustedUseLogged.has(origin) || this._trustedCredentialsOrigins.includes(origin))
|
|
174065
|
+
return;
|
|
174066
|
+
this._untrustedUseLogged.add(origin);
|
|
174067
|
+
_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(loggerCategory, `Credentials sent to origin '${origin}' which is not in MapLayerFormatRegistry.trustedCredentialsOrigins; `
|
|
174068
|
+
+ "this request would be blocked if restrictCredentialsToTrustedOrigins were enabled.");
|
|
174069
|
+
}
|
|
173807
174070
|
_formats = new Map();
|
|
173808
174071
|
isRegistered(formatId) { return this._formats.get(formatId) !== undefined; }
|
|
173809
174072
|
register(formatClass) {
|
|
@@ -173969,6 +174232,14 @@ class WmsMapLayerFormat extends ImageryMapLayerFormat {
|
|
|
173969
174232
|
return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.Valid, subLayers };
|
|
173970
174233
|
}
|
|
173971
174234
|
catch (err) {
|
|
174235
|
+
if (err instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError) {
|
|
174236
|
+
let blockedOrigin;
|
|
174237
|
+
try {
|
|
174238
|
+
blockedOrigin = new URL(err.url).origin;
|
|
174239
|
+
}
|
|
174240
|
+
catch { /* non-hierarchical URL */ }
|
|
174241
|
+
return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
|
|
174242
|
+
}
|
|
173972
174243
|
let status = _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidUrl;
|
|
173973
174244
|
if (err?.status === 401) {
|
|
173974
174245
|
status = ((userName && password) ? _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidCredentials : _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.RequireAuth);
|
|
@@ -174034,6 +174305,14 @@ class WmtsMapLayerFormat extends ImageryMapLayerFormat {
|
|
|
174034
174305
|
return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.Valid, subLayers };
|
|
174035
174306
|
}
|
|
174036
174307
|
catch (err) {
|
|
174308
|
+
if (err instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError) {
|
|
174309
|
+
let blockedOrigin;
|
|
174310
|
+
try {
|
|
174311
|
+
blockedOrigin = new URL(err.url).origin;
|
|
174312
|
+
}
|
|
174313
|
+
catch { /* non-hierarchical URL */ }
|
|
174314
|
+
return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
|
|
174315
|
+
}
|
|
174037
174316
|
let status = _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidUrl;
|
|
174038
174317
|
if (err?.status === 401) {
|
|
174039
174318
|
status = ((userName && password) ? _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidCredentials : _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.RequireAuth);
|
|
@@ -174098,7 +174377,9 @@ const internalMapLayerImageryFormats = [WmsMapLayerFormat, WmtsMapLayerFormat, A
|
|
|
174098
174377
|
__webpack_require__.r(__webpack_exports__);
|
|
174099
174378
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
174100
174379
|
/* harmony export */ MapLayerImageryProvider: () => (/* binding */ MapLayerImageryProvider),
|
|
174101
|
-
/* harmony export */ MapLayerImageryProviderStatus: () => (/* binding */ MapLayerImageryProviderStatus)
|
|
174380
|
+
/* harmony export */ MapLayerImageryProviderStatus: () => (/* binding */ MapLayerImageryProviderStatus),
|
|
174381
|
+
/* harmony export */ escapeHtml: () => (/* binding */ escapeHtml),
|
|
174382
|
+
/* harmony export */ tryGetOrigin: () => (/* binding */ tryGetOrigin)
|
|
174102
174383
|
/* harmony export */ });
|
|
174103
174384
|
/* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
|
|
174104
174385
|
/* harmony import */ var _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @itwin/core-common */ "../../core/common/lib/esm/core-common.js");
|
|
@@ -174125,6 +174406,34 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
174125
174406
|
const tileImageSize = 256, untiledImageSize = 256;
|
|
174126
174407
|
const earthRadius = 6378137;
|
|
174127
174408
|
const doDebugToolTips = false;
|
|
174409
|
+
/** Escapes HTML metacharacters so the text renders literally when assigned to `innerHTML`.
|
|
174410
|
+
* Use for any server- or user-supplied string that ends up in the map tooltip, which is rendered
|
|
174411
|
+
* as HTML by [[MapLayerTileTreeReference.getToolTip]].
|
|
174412
|
+
* @internal
|
|
174413
|
+
*/
|
|
174414
|
+
function escapeHtml(text) {
|
|
174415
|
+
return text.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
|
|
174416
|
+
}
|
|
174417
|
+
/** Returns the origin (scheme + host + port) of the given URL, or undefined if it cannot be parsed or does
|
|
174418
|
+
* not denote a distinct network origin.
|
|
174419
|
+
*
|
|
174420
|
+
* Only `http:` and `https:` URLs yield an origin. Every other scheme is rejected because opaque URLs
|
|
174421
|
+
* — `file:`, `data:`, `about:`, `blob:null`, and the custom protocols Electron hosts commonly register —
|
|
174422
|
+
* all serialize to the literal string `"null"`. Comparing those would make unrelated URLs look same-origin,
|
|
174423
|
+
* so a single trusted entry could unlock all of them. Callers use this for credential-trust decisions, and
|
|
174424
|
+
* returning `undefined` keeps those decisions fail-closed.
|
|
174425
|
+
* @internal
|
|
174426
|
+
*/
|
|
174427
|
+
function tryGetOrigin(url) {
|
|
174428
|
+
let parsed;
|
|
174429
|
+
try {
|
|
174430
|
+
parsed = new URL(url);
|
|
174431
|
+
}
|
|
174432
|
+
catch {
|
|
174433
|
+
return undefined;
|
|
174434
|
+
}
|
|
174435
|
+
return (parsed.protocol === "http:" || parsed.protocol === "https:") ? parsed.origin : undefined;
|
|
174436
|
+
}
|
|
174128
174437
|
/** The status of the map layer imagery provider that lets you know if authentication is needed to request tiles.
|
|
174129
174438
|
* @public
|
|
174130
174439
|
*/
|
|
@@ -174132,6 +174441,12 @@ var MapLayerImageryProviderStatus;
|
|
|
174132
174441
|
(function (MapLayerImageryProviderStatus) {
|
|
174133
174442
|
MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["Valid"] = 0] = "Valid";
|
|
174134
174443
|
MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["RequireAuth"] = 1] = "RequireAuth";
|
|
174444
|
+
/** A request received an authentication challenge, but credentials were withheld because the request origin
|
|
174445
|
+
* is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
|
|
174446
|
+
* The blocked origins are available via [[MapLayerImageryProvider.blockedOrigins]].
|
|
174447
|
+
* @beta
|
|
174448
|
+
*/
|
|
174449
|
+
MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["UntrustedOrigin"] = 2] = "UntrustedOrigin";
|
|
174135
174450
|
})(MapLayerImageryProviderStatus || (MapLayerImageryProviderStatus = {}));
|
|
174136
174451
|
/** Abstract class for map layer imagery providers.
|
|
174137
174452
|
* Map layer imagery providers request and provide tile images and other data. Each map layer from a separate source needs its own imagery provider object.
|
|
@@ -174149,7 +174464,41 @@ class MapLayerImageryProvider {
|
|
|
174149
174464
|
/** @internal */
|
|
174150
174465
|
_status = MapLayerImageryProviderStatus.Valid;
|
|
174151
174466
|
/** @internal */
|
|
174152
|
-
|
|
174467
|
+
_blockedOrigins = new Set();
|
|
174468
|
+
/** Origins of requests for which credentials were withheld because they are not trusted
|
|
174469
|
+
* (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
|
|
174470
|
+
* Populated when [[status]] transitions to [[MapLayerImageryProviderStatus.UntrustedOrigin]];
|
|
174471
|
+
* [[onStatusChanged]] is raised again each time a new origin is added. Cleared by [[resetStatus]].
|
|
174472
|
+
* @beta
|
|
174473
|
+
*/
|
|
174474
|
+
get blockedOrigins() { return [...this._blockedOrigins]; }
|
|
174475
|
+
/** Origins for which a previous SSO handshake (i.e. Windows Authentication) succeeded.
|
|
174476
|
+
* Browser credentials are only included for subsequent requests targeting these origins,
|
|
174477
|
+
* so that a successful handshake with one host does not leak credentials to other hosts
|
|
174478
|
+
* this provider may contact.
|
|
174479
|
+
* @internal
|
|
174480
|
+
*/
|
|
174481
|
+
_ssoSucceededOrigins = new Set();
|
|
174482
|
+
/** Returns true if browser credentials should be included for the given URL because a previous
|
|
174483
|
+
* SSO handshake succeeded for its origin AND the origin is still allowed by the current policy
|
|
174484
|
+
* (see [[MapLayerFormatRegistry.isSsoAllowed]]). Re-checking the policy ensures a handshake recorded
|
|
174485
|
+
* while enforcement was disabled — or before an origin was removed from
|
|
174486
|
+
* [[MapLayerFormatRegistry.trustedCredentialsOrigins]] — does not keep latching credentials on.
|
|
174487
|
+
* @internal
|
|
174488
|
+
*/
|
|
174489
|
+
includeUserCredentials(url) {
|
|
174490
|
+
const origin = tryGetOrigin(url);
|
|
174491
|
+
return origin !== undefined && this._ssoSucceededOrigins.has(origin) && this.isSsoAllowed(url);
|
|
174492
|
+
}
|
|
174493
|
+
/** Records that an SSO handshake succeeded for the given URL's origin, so subsequent requests
|
|
174494
|
+
* to that origin include browser credentials without going through another 401 challenge.
|
|
174495
|
+
* @internal
|
|
174496
|
+
*/
|
|
174497
|
+
recordSsoSucceeded(url) {
|
|
174498
|
+
const origin = tryGetOrigin(url);
|
|
174499
|
+
if (origin !== undefined)
|
|
174500
|
+
this._ssoSucceededOrigins.add(origin);
|
|
174501
|
+
}
|
|
174153
174502
|
/** @internal */
|
|
174154
174503
|
onFirstRequestCompleted = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
|
|
174155
174504
|
/** @internal */
|
|
@@ -174165,7 +174514,17 @@ class MapLayerImageryProvider {
|
|
|
174165
174514
|
* @public
|
|
174166
174515
|
*/
|
|
174167
174516
|
get supportsMapFeatureInfo() { return false; }
|
|
174168
|
-
|
|
174517
|
+
/** Reset the provider's status to [[MapLayerImageryProviderStatus.Valid]] and clear the list of
|
|
174518
|
+
* [[blockedOrigins]] accumulated while in the [[MapLayerImageryProviderStatus.UntrustedOrigin]] state.
|
|
174519
|
+
* Raises [[onStatusChanged]] if the status actually changes.
|
|
174520
|
+
* Typically called after the user has provided credentials or the application has updated
|
|
174521
|
+
* [[MapLayerFormatRegistry.trustedCredentialsOrigins]], so that subsequent requests are re-attempted.
|
|
174522
|
+
* @beta
|
|
174523
|
+
*/
|
|
174524
|
+
resetStatus() {
|
|
174525
|
+
this._blockedOrigins.clear();
|
|
174526
|
+
this.setStatus(MapLayerImageryProviderStatus.Valid);
|
|
174527
|
+
}
|
|
174169
174528
|
/** @internal */
|
|
174170
174529
|
get tileSize() { return this._usesCachedTiles ? tileImageSize : untiledImageSize; }
|
|
174171
174530
|
/** @internal */
|
|
@@ -174339,6 +174698,32 @@ class MapLayerImageryProvider {
|
|
|
174339
174698
|
(0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.setBasicAuthorization)(headers, this._settings.userName, this._settings.password);
|
|
174340
174699
|
}
|
|
174341
174700
|
}
|
|
174701
|
+
/** Returns true if the given URL has the same origin as this layer's settings URL.
|
|
174702
|
+
* Used to avoid leaking credentials to third-party hosts.
|
|
174703
|
+
* @internal
|
|
174704
|
+
*/
|
|
174705
|
+
matchesSettingsUrlOrigin(url) {
|
|
174706
|
+
const origin = tryGetOrigin(url);
|
|
174707
|
+
return origin !== undefined && origin === tryGetOrigin(this._settings.url);
|
|
174708
|
+
}
|
|
174709
|
+
/** Returns true if the basic-auth credentials from the layer settings may be attached to a request to the given URL.
|
|
174710
|
+
* Always true unless [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is enabled (opt-in).
|
|
174711
|
+
* When enabled, the origin of this layer's settings URL is implicitly trusted (the credentials belong to that
|
|
174712
|
+
* server); other origins must be listed in [[MapLayerFormatRegistry.trustedCredentialsOrigins]].
|
|
174713
|
+
* See [[MapLayerFormatRegistry.isCredentialsSharingAllowed]].
|
|
174714
|
+
* @internal
|
|
174715
|
+
*/
|
|
174716
|
+
isCredentialsSharingAllowed(url) {
|
|
174717
|
+
return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, this._settings.url);
|
|
174718
|
+
}
|
|
174719
|
+
/** Returns true if a request to the given URL may be retried with browser credentials included
|
|
174720
|
+
* (i.e. SSO / Windows Authentication) after an NTLM or Negotiate http 401 challenge.
|
|
174721
|
+
* See [[MapLayerFormatRegistry.isSsoAllowed]].
|
|
174722
|
+
* @internal
|
|
174723
|
+
*/
|
|
174724
|
+
isSsoAllowed(url) {
|
|
174725
|
+
return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(url);
|
|
174726
|
+
}
|
|
174342
174727
|
/** @internal */
|
|
174343
174728
|
async makeTileRequest(url, timeoutMs, authorization) {
|
|
174344
174729
|
// We want to complete the first request before letting other requests go;
|
|
@@ -174358,40 +174743,132 @@ class MapLayerImageryProvider {
|
|
|
174358
174743
|
throw new Error("fetch call failed");
|
|
174359
174744
|
return response;
|
|
174360
174745
|
}
|
|
174746
|
+
/** Records the given URL's origin and transitions the status to [[MapLayerImageryProviderStatus.UntrustedOrigin]].
|
|
174747
|
+
* Called when a request received an authentication challenge that could not be answered because the origin
|
|
174748
|
+
* is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
|
|
174749
|
+
* Raises [[onStatusChanged]] on the status transition, and again whenever a new origin is added.
|
|
174750
|
+
* @internal
|
|
174751
|
+
*/
|
|
174752
|
+
reportBlockedOrigin(url) {
|
|
174753
|
+
const origin = tryGetOrigin(url) ?? url;
|
|
174754
|
+
const isNewOrigin = !this._blockedOrigins.has(origin);
|
|
174755
|
+
this._blockedOrigins.add(origin);
|
|
174756
|
+
if (this._status !== MapLayerImageryProviderStatus.UntrustedOrigin)
|
|
174757
|
+
this.setStatus(MapLayerImageryProviderStatus.UntrustedOrigin);
|
|
174758
|
+
else if (isNewOrigin)
|
|
174759
|
+
this.onStatusChanged.raiseEvent(this); // status unchanged, but a new origin was blocked
|
|
174760
|
+
}
|
|
174761
|
+
/** Logs a warning (once per origin, app-wide) when credentials are sent to an origin that would be blocked
|
|
174762
|
+
* if [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] were enabled.
|
|
174763
|
+
* Helps applications discover the origins they need to whitelist before opting in to the restriction.
|
|
174764
|
+
* See [[MapLayerFormatRegistry.logUntrustedOriginUse]].
|
|
174765
|
+
* @internal
|
|
174766
|
+
*/
|
|
174767
|
+
logUntrustedOriginUse(url) {
|
|
174768
|
+
_IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(url);
|
|
174769
|
+
}
|
|
174770
|
+
/** The redirect policy to apply to a request that carries browser credentials (see [[includeUserCredentials]]).
|
|
174771
|
+
*
|
|
174772
|
+
* When [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is enabled, redirects are refused
|
|
174773
|
+
* outright (`"error"`). `fetch` cannot be asked to follow only same-origin redirects, and by the time a
|
|
174774
|
+
* followed redirect can be inspected the credentials have already been delivered to the destination — so
|
|
174775
|
+
* refusing is the only way to honour the guarantee that credentials reach none but the origins listed in
|
|
174776
|
+
* [[MapLayerFormatRegistry.trustedCredentialsOrigins]]. Legitimate same-origin redirects fail as a result;
|
|
174777
|
+
* that is the cost of the opt-in restriction.
|
|
174778
|
+
*
|
|
174779
|
+
* When the restriction is disabled (the default), redirects are followed as before and
|
|
174780
|
+
* [[checkCredentialedRedirect]] reports the destination after the fact.
|
|
174781
|
+
* @internal
|
|
174782
|
+
*/
|
|
174783
|
+
get credentialedRedirect() {
|
|
174784
|
+
return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined;
|
|
174785
|
+
}
|
|
174786
|
+
/** Detects that a request carrying browser credentials (see [[includeUserCredentials]]) was transparently
|
|
174787
|
+
* redirected to a different origin, and reports or logs that origin.
|
|
174788
|
+
*
|
|
174789
|
+
* This is a **best-effort, after-the-fact** signal used only while
|
|
174790
|
+
* [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is disabled, where credentialed requests
|
|
174791
|
+
* still follow redirects (see [[credentialedRedirect]]). It cannot prevent the exposure — the credentials
|
|
174792
|
+
* have already been sent — and it does not fire at all when the destination denies CORS, because `fetch`
|
|
174793
|
+
* then rejects instead of returning a `Response`. The destination origin is never latched as SSO-succeeded,
|
|
174794
|
+
* so credentials do not keep flowing to it.
|
|
174795
|
+
* @internal
|
|
174796
|
+
*/
|
|
174797
|
+
checkCredentialedRedirect(requestedUrl, response) {
|
|
174798
|
+
const finalOrigin = tryGetOrigin(response.url);
|
|
174799
|
+
if (!response.url || finalOrigin === undefined || finalOrigin === tryGetOrigin(requestedUrl))
|
|
174800
|
+
return;
|
|
174801
|
+
if (!this.isSsoAllowed(response.url))
|
|
174802
|
+
this.reportBlockedOrigin(response.url);
|
|
174803
|
+
else
|
|
174804
|
+
this.logUntrustedOriginUse(response.url); // no-op when the restriction is enabled
|
|
174805
|
+
}
|
|
174361
174806
|
/** @internal */
|
|
174362
174807
|
async makeRequest(url, timeoutMs, authorization) {
|
|
174363
174808
|
let response;
|
|
174364
174809
|
let headers;
|
|
174365
174810
|
let hasCreds = false;
|
|
174811
|
+
// Whether this request had basic-auth credentials of its own to offer. Requests carrying a caller-supplied
|
|
174812
|
+
// `authorization` are excluded: those bypass the origin policy entirely.
|
|
174813
|
+
const hasSettingsCreds = !authorization && !!this._settings.userName && !!this._settings.password;
|
|
174366
174814
|
if (authorization) {
|
|
174367
174815
|
headers = new Headers();
|
|
174368
174816
|
headers.set("Authorization", authorization);
|
|
174369
174817
|
}
|
|
174370
|
-
else if (
|
|
174371
|
-
|
|
174372
|
-
|
|
174373
|
-
|
|
174818
|
+
else if (hasSettingsCreds) {
|
|
174819
|
+
if (this.isCredentialsSharingAllowed(url)) {
|
|
174820
|
+
hasCreds = true;
|
|
174821
|
+
headers = new Headers();
|
|
174822
|
+
this.setRequestAuthorization(headers);
|
|
174823
|
+
if (!this.matchesSettingsUrlOrigin(url))
|
|
174824
|
+
this.logUntrustedOriginUse(url);
|
|
174825
|
+
}
|
|
174374
174826
|
}
|
|
174827
|
+
const includeCredentials = this.includeUserCredentials(url);
|
|
174375
174828
|
const opts = {
|
|
174376
174829
|
method: "GET",
|
|
174377
174830
|
headers,
|
|
174378
|
-
credentials:
|
|
174831
|
+
credentials: includeCredentials ? "include" : undefined,
|
|
174832
|
+
redirect: includeCredentials ? this.credentialedRedirect : undefined,
|
|
174379
174833
|
};
|
|
174380
174834
|
if (timeoutMs !== undefined)
|
|
174381
174835
|
(0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.setRequestTimeout)(opts, timeoutMs);
|
|
174382
174836
|
response = await fetch(url, opts);
|
|
174837
|
+
if (includeCredentials)
|
|
174838
|
+
this.checkCredentialedRedirect(url, response);
|
|
174839
|
+
// fetch follows redirects transparently, so all trust decisions below target the final
|
|
174840
|
+
// (post-redirect) URL reported by the response, not the URL we asked for.
|
|
174841
|
+
const challengedUrl = response.url || url;
|
|
174383
174842
|
if (response.status === 401
|
|
174384
174843
|
&& (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])
|
|
174385
|
-
&& !
|
|
174844
|
+
&& !includeCredentials
|
|
174386
174845
|
&& !hasCreds) {
|
|
174387
|
-
|
|
174388
|
-
|
|
174389
|
-
|
|
174390
|
-
|
|
174391
|
-
|
|
174392
|
-
|
|
174393
|
-
|
|
174846
|
+
if (this.isSsoAllowed(challengedUrl)) {
|
|
174847
|
+
// Removed the previous headers and make sure "include" credentials is set
|
|
174848
|
+
opts.headers = undefined;
|
|
174849
|
+
opts.credentials = "include";
|
|
174850
|
+
// A Negotiate/NTLM handshake is normally a same-URL 401 round-trip, but in legacy mode we preserve
|
|
174851
|
+
// the previous behavior and allow the browser to follow redirects after the authenticated retry.
|
|
174852
|
+
opts.redirect = _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined;
|
|
174853
|
+
this.logUntrustedOriginUse(challengedUrl);
|
|
174854
|
+
// We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
|
|
174855
|
+
response = await fetch(challengedUrl, opts);
|
|
174856
|
+
if (response.status === 200) {
|
|
174857
|
+
this.recordSsoSucceeded(challengedUrl); // avoid going through 401 challenges over and over for this origin
|
|
174858
|
+
}
|
|
174394
174859
|
}
|
|
174860
|
+
else {
|
|
174861
|
+
this.reportBlockedOrigin(challengedUrl);
|
|
174862
|
+
}
|
|
174863
|
+
}
|
|
174864
|
+
else if ((response.status === 401 || response.status === 403) && hasSettingsCreds && !this.isCredentialsSharingAllowed(challengedUrl)) {
|
|
174865
|
+
// Some servers answer an unauthenticated request with 403 (Forbidden) rather than a 401 challenge;
|
|
174866
|
+
// since this request could not present its credentials to the challenging origin, either status most
|
|
174867
|
+
// likely results from that. The permission is recomputed for the challenged URL rather than reusing the
|
|
174868
|
+
// decision made for the requested one: `fetch` strips the Authorization header when it follows a
|
|
174869
|
+
// cross-origin redirect, so a trusted request can still arrive unauthenticated at an untrusted origin,
|
|
174870
|
+
// and conversely a request that started out untrusted may end up at an origin that is trusted.
|
|
174871
|
+
this.reportBlockedOrigin(challengedUrl);
|
|
174395
174872
|
}
|
|
174396
174873
|
return response;
|
|
174397
174874
|
}
|
|
@@ -174423,16 +174900,28 @@ class MapLayerImageryProvider {
|
|
|
174423
174900
|
}
|
|
174424
174901
|
/** @internal */
|
|
174425
174902
|
async toolTipFromUrl(strings, url) {
|
|
174426
|
-
|
|
174427
|
-
this.
|
|
174903
|
+
let headers;
|
|
174904
|
+
if (this.isCredentialsSharingAllowed(url)) {
|
|
174905
|
+
headers = new Headers();
|
|
174906
|
+
this.setRequestAuthorization(headers);
|
|
174907
|
+
}
|
|
174428
174908
|
try {
|
|
174909
|
+
const includeCredentials = this.includeUserCredentials(url);
|
|
174429
174910
|
const response = await fetch(url, {
|
|
174430
174911
|
method: "GET",
|
|
174431
174912
|
headers,
|
|
174432
|
-
credentials:
|
|
174913
|
+
credentials: includeCredentials ? "include" : undefined,
|
|
174914
|
+
redirect: includeCredentials ? this.credentialedRedirect : undefined,
|
|
174433
174915
|
});
|
|
174434
|
-
|
|
174435
|
-
|
|
174916
|
+
if (includeCredentials)
|
|
174917
|
+
this.checkCredentialedRedirect(url, response);
|
|
174918
|
+
let text = await response.text();
|
|
174919
|
+
if (text) {
|
|
174920
|
+
// Tooltip content (e.g. WMS GetFeatureInfo responses) is rendered as HTML downstream and may
|
|
174921
|
+
// deliberately contain markup; text from origins not trusted for credentials is escaped.
|
|
174922
|
+
// fetch follows redirects transparently, so the text may come from a different origin than requested.
|
|
174923
|
+
if (!this.isCredentialsSharingAllowed(response.url || url))
|
|
174924
|
+
text = escapeHtml(text);
|
|
174436
174925
|
strings.push(text);
|
|
174437
174926
|
}
|
|
174438
174927
|
}
|
|
@@ -174612,6 +175101,12 @@ var MapLayerSourceStatus;
|
|
|
174612
175101
|
/** Format is not compatible with the URL provided.
|
|
174613
175102
|
*/
|
|
174614
175103
|
MapLayerSourceStatus[MapLayerSourceStatus["IncompatibleFormat"] = 7] = "IncompatibleFormat";
|
|
175104
|
+
/** Authentication could not be attempted because the source's origin is not trusted
|
|
175105
|
+
* (see [MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]($frontend)). Add the origin to
|
|
175106
|
+
* [MapLayerFormatRegistry.trustedCredentialsOrigins]($frontend) rather than prompting for credentials.
|
|
175107
|
+
* @beta
|
|
175108
|
+
*/
|
|
175109
|
+
MapLayerSourceStatus[MapLayerSourceStatus["UntrustedOrigin"] = 8] = "UntrustedOrigin";
|
|
174615
175110
|
})(MapLayerSourceStatus || (MapLayerSourceStatus = {}));
|
|
174616
175111
|
/** A source for map layers. These may be catalogued for convenient use by users or applications.
|
|
174617
175112
|
* @public
|
|
@@ -174899,10 +175394,8 @@ class MapLayerTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_3__.T
|
|
|
174899
175394
|
const tree = this.treeOwner.tileTree;
|
|
174900
175395
|
if (undefined === tree || hit.iModel !== tree.iModel || tree.modelId !== hit.sourceId)
|
|
174901
175396
|
return undefined;
|
|
174902
|
-
const strings = [];
|
|
174903
|
-
strings.push(`Map Layer: ${this._layerSettings.name}`);
|
|
174904
175397
|
const div = document.createElement("div");
|
|
174905
|
-
div.
|
|
175398
|
+
div.textContent = `Map Layer: ${this._layerSettings.name}`;
|
|
174906
175399
|
return div;
|
|
174907
175400
|
}
|
|
174908
175401
|
decorate(_context) {
|
|
@@ -176611,7 +177104,9 @@ class MapTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_7__.TileTr
|
|
|
176611
177104
|
let carto;
|
|
176612
177105
|
const strings = [];
|
|
176613
177106
|
const getTooltipFunc = async (imageryTreeRef, quadId, cartoGraphic, imageryTree) => {
|
|
176614
|
-
|
|
177107
|
+
// innerHTML is used below because imageryLoader.getToolTip may deliberately supply markup.
|
|
177108
|
+
const layerName = (0,_internal__WEBPACK_IMPORTED_MODULE_7__.escapeHtml)(imageryTreeRef.layerSettings.name);
|
|
177109
|
+
strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_4__.IModelApp.localization.getLocalizedString("iModelJs:MapLayers.ImageryLayer")}: ${layerName}`);
|
|
176615
177110
|
carto = cartoGraphic;
|
|
176616
177111
|
await imageryTree.imageryLoader.getToolTip(strings, quadId, cartoGraphic, imageryTree);
|
|
176617
177112
|
};
|
|
@@ -334493,7 +334988,7 @@ var loadLanguages = instance.loadLanguages;
|
|
|
334493
334988
|
(module) {
|
|
334494
334989
|
|
|
334495
334990
|
"use strict";
|
|
334496
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.13.0-dev.
|
|
334991
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.13.0-dev.18","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s build:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run build:test-worker && vitest --run","cover":"npm run build:test-worker && vitest --run","build:test-worker":"vite build --config ./src/test/worker/vite.config.mts 1>&2","build:workers":"rimraf lib/workers/webpack && vite build --config ./src/workers/ImdlParser/vite.config.mts 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.11","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/node":"~20.17.0","@types/sinon":"^17.0.2","@vitest/browser-playwright":"^4.1.10","@vitest/coverage-v8":"^4.1.10","cpx2":"^8.0.0","eslint":"^9.31.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","typescript":"~5.6.2","vite":"^6.4.3","vitest":"^4.1.10","vite-plugin-static-copy":"2.2.0"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"~4.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
|
|
334497
334992
|
|
|
334498
334993
|
/***/ }
|
|
334499
334994
|
|