Esri / esri-leaflet-vector

Display ArcGIS Online vector basemaps w/ Esri Leaflet
51 stars 53 forks source link

Salesforce Lightning Locker Service Compatibilty #172

Open GlynAndersonSlalom opened 1 year ago

GlynAndersonSlalom commented 1 year ago

Describe the bug

Esri Leaflet Vector appears to be incompatible with Salesforce Lightning Locker Service. We are able to use Esri Leaflet in a Lightning Web Component (LWC) to render maps in Lightning Experience (the internal SF UI) and Experience Cloud (the external-facing "portal" UI), but when we add the Esri Leaflet Vector plugin, it triggers Locker Service, a security feature which protects against cross-site scripting. We've whitelisted multiple domains (including .leafletjs.com and .arcgis.com) but the problem persists. I've also looked through the Leaflet source code for domains that might need to be whitelisted.

We've worked around the problem by embedding our LWC into an Aura component configured to run using Salesforce API version 39.0, which pre-dates Locker Service. This is a short-term workaround, as Salesforce has already deprecated version up through 30.0 and will continue to deprecate API versions (the current version is 57.0).

The ask here is either to ensure there is no cross-site scripting in the Vector code, or to document any domains that need to be whitelisted to avoid this issue.

Reproduction

To reproduce, create a Lightning Web Component that imports the Esri Leaflet Vector plugin:

import LEAFLET from '@salesforce/resourceUrl/leaflet';
import ESRILEAFLET from '@salesforce/resourceUrl/esriLeaflet';
import ESRILEAFLETVECTOR from '@salesforce/resourceUrl/esriLeafletVector';
import ESRILEAFLETGEOCODER from '@salesforce/resourceUrl/esriLeafletGeocoder';

and embed it in a Lightning App Builder page or Experience Builder page with Content Security Policy set to Strict.

Logs

No response

System Info

/* Leaflet 1.9.3, a JS library for interactive maps. https://leafletjs.com
/* esri-leaflet - v3.0.10 - Tue Jan 17 2023 09:24:14 GMT-0600 (Central Standard Time)
/* esri-leaflet-vector - v4.0.1 - Thu Feb 23 2023 14:15:02 GMT-0600 (Central Standard Time)
/* esri-leaflet-geocoder - v3.1.4 - Thu Feb 23 2023 13:29:25 GMT-0600 (Central Standard Time)

Additional Information

No response

gavinr commented 1 year ago

Hi @GlynAndersonSlalom, thank you for the report.

I see the import statements, but can you please post a full minimal reproduction case that you're using for your Lightening web component, so we can try to replicate what you're seeing? Thank you!

GlynAndersonSlalom commented 1 year ago

Gavin, I'll get this to you as soon as possible, but that could be a couple weeks as the developer of the component just went on PTO for a while. Thanks for the quick response!

jsh4478 commented 1 year ago

esriLeafletVectorReproduce.zip

@gavinr Hey Gavin, I've attached an example that you should be able to use to reproduce. Steps needed:

  1. Take leaflet.zip, esriLeaflet.zip, esriLeafletVector.zip and upload them as static resources with the resource names matching the zip file. Salesforce does not allow CDN so I had to download the js, css and image files from the CDN links provided in documentation to create these zip files myself.
  2. Create custom labels named ArcGIS_Token, ArcGIS_BaseEnum, ArcGIS_ParcelLayerURL and populate those accordingly.
  3. Deploy the esriLeafletBugReproduce LWC into your salesforce org. This LWC uses nested promises to load the leaflet dependencies, as the required loadScript method runs asynchronously and created a race condition when trying to load them all at once.
  4. Create a tab for the LWC, add the tab to an app and then navigate to that app.

The specific error I receive is 'L.esri.Vector.vectorBasemapLayer is not a function'. Once either of the workarounds are implemented, this goes away and draws the features defined in the layer.

As Glyn mentioned, my workarounds have been:

Let me know if you have any questions or issues implementing these steps and thanks for looking into this!