Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GSLUX-664: Proxyurl as a setting from v3 #95

Merged
merged 5 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
VITE_USE_PROXYURL=true
VITE_PROXYURL_WMS="https://map.geoportail.lu/ogcproxywms"
VITE_PROXYURL_REMOTE="https://map.geoportail.lu/httpsproxy"
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.prettierignore

## editors
/.idea
*.iml
Expand All @@ -24,6 +26,7 @@
/dist/
/out-tsc/
.parcel-cache
.env

# fixtures
/src/__fixtures__/
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,15 @@ RUN mkdir /etc/static-ngeo/web-components \
&& cp -r /usr/lib/node_modules/luxembourg-geoportail/bundle/assets/ /etc/static-ngeo/web-components/assets/ \
&& cp /usr/lib/node_modules/luxembourg-geoportail/bundle/style.css /etc/static-ngeo/web-components/style.css
```

### Initialize app settings

Configure your proxy urls, otherwise, layers may not display correctly.

```js
// Inside your App.vue, or in your custom js if using lux as a lib:
const proxyWmsUrl = 'https://map.geoportail.lu/ogcproxywms'
const remoteProxyWms = 'https://map.geoportail.lu/httpsproxy'

proxyUrlHelper.init(proxyWmsUrl, remoteProxyWms)
```
7,135 changes: 3,576 additions & 3,559 deletions bundle/lux.dist.mjs

Large diffs are not rendered by default.

62 changes: 31 additions & 31 deletions bundle/lux.dist.umd.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"test:unit": "vitest --environment jsdom --root .",
"test:unit:ci": "vitest run --environment jsdom --coverage",
"test:e2e": "INSRUMENT_COVERAGE=true start-server-and-test preview :4173 'cypress open --e2e'",
"test:e2e:ci": "INSRUMENT_COVERAGE=true start-server-and-test 'vite dev --port 4173' :4173 'cypress run --e2e'",
"test:e2e:ci": "INSRUMENT_COVERAGE=true start-server-and-test 'VITE_USE_PROXYURL=false vite dev --port 4173' :4173 'cypress run --e2e'",
"test:e2e:dev": "INSRUMENT_COVERAGE=true start-server-and-test 'vite dev --port 4173' :4173 'cypress open --e2e'",
"coverage-report": "nyc report",
"type-check:dev": "npm run type-check -- --watch",
Expand Down
5 changes: 4 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@
import { statePersistorLayersOpenService } from '@/services/state-persistor/state-persistor-layersopen.service'
import { statePersistorStyleService } from '@/services/state-persistor/state-persistor-bgstyle.service'
import { statePersistorMyMapService } from '@/services/state-persistor/state-persistor-mymap.service'

import { useAppStore } from '@/stores/app.store'
import useMap from '@/composables/map/map.composable'
import traverseLayer from '@/lib/tools.js'

const appStore = useAppStore()

// Important, keep order!
statePersistorMyMapService.bootstrap()
statePersistorLayersService.bootstrap()
Expand All @@ -34,7 +37,7 @@
statePersistorStyleService.bootstrapStyle()
statePersistorBgLayerService.bootstrap()

const { layersOpen, styleEditorOpen } = storeToRefs(useAppStore())
const { layersOpen, styleEditorOpen } = storeToRefs(appStore)

watch(layersOpen, () =>
setTimeout(() => {
Expand All @@ -56,7 +59,7 @@
// the utility function traverseLayer is used as a workaround until OL is updated to 6.15
// then the function getAllLayers below (added in OL v.6.10.0) can be used
// map.getAllLayers().forEach(layer => {
traverseLayer(map.getLayerGroup(), [], (layer: any) => {

Check warning on line 62 in src/App.vue

View workflow job for this annotation

GitHub Actions / build-lint-test

Unexpected any. Specify a different type
if (layer instanceof MapLibreLayer) {
;(layer as MapLibreLayer).getMapLibreMap().resize()
}
Expand Down
2 changes: 2 additions & 0 deletions src/bundle/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { statePersistorThemeService } from '@/services/state-persistor/state-per
import { statePersistorLayersOpenService } from '@/services/state-persistor/state-persistor-layersopen.service'
import { statePersistorStyleService } from '@/services/state-persistor/state-persistor-bgstyle.service'
import { statePersistorMyMapService } from '@/services/state-persistor/state-persistor-mymap.service'
import { proxyUrlHelper } from '@/services/proxyurl/proxyurl.helper'
import { themeSelectorService } from '@/components/theme-selector/theme-selector.service'
import MapLibreLayer from '@/lib/ol-mapbox-layer'

Expand Down Expand Up @@ -100,6 +101,7 @@ export {
FooterBar,
LayerPanel,
SliderComparator,
proxyUrlHelper,
useLayers,
useMap,
useMvtStyles,
Expand Down
14 changes: 7 additions & 7 deletions src/components/remote-layers/remote-layers.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script setup lang="ts">
import { shallowRef, ShallowRef, watchEffect } from 'vue'
import { storeToRefs } from 'pinia'
import { useTranslation } from 'i18next-vue'

import { useAppStore } from '@/stores/app.store'
import { useMapStore } from '@/stores/map.store'
import DropdownList from '@/components/common/dropdown-list.vue'
import ModalDialog from '@/components/common/modal-dialog.vue'
Expand All @@ -10,16 +12,14 @@ import LayerTreeNode from '@/components/layer-tree/layer-tree-node.vue'
import { LayerTreeNodeModel } from '@/components/layer-tree/layer-tree.model'
import { layerTreeService } from '@/components/layer-tree/layer-tree.service'
import useLayers from '@/composables/layers/layers.composable'

import {
remoteLayersToLayerTreeMapper,
remoteLayerToLayer,
} from '../../services/remote-layers/remote-layers.mapper'
import { remoteLayersService } from '../../services/remote-layers/remote-layers.service'
import { OgcClientWmsEndpoint } from '../../services/remote-layers/remote-layers.model'
} from '@/services/remote-layers/remote-layers.mapper'
import { remoteLayersService } from '@/services/remote-layers/remote-layers.service'
import { OgcClientWmsEndpoint } from '@/services/remote-layers/remote-layers.model'
import { proxyUrlHelper } from '@/services/proxyurl/proxyurl.helper'
import { WmtsEndpoint } from '@/services/remote-layers/wmts.endpoint'
import { storeToRefs } from 'pinia'
import { useAppStore } from '@/stores/app.store'

const { t } = useTranslation()
const mapStore = useMapStore()
Expand Down Expand Up @@ -110,7 +110,7 @@ function toggleLayer(node: LayerTreeNodeModel) {
const layer = layers.initLayer(
remoteLayerToLayer({
id,
url: remoteLayersService.getProxyfiedUrl(currentRemoteUrl),
url: proxyUrlHelper.getProxyfiedUrl(currentRemoteUrl),
remoteLayer,
})
)
Expand Down
7 changes: 4 additions & 3 deletions src/services/ol-layer/ol-layer-wms.helper.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import ImageLayer from 'ol/layer/Image'
import ImageWMS from 'ol/source/ImageWMS'

import { proxyUrlHelper } from '@/services/proxyurl/proxyurl.helper'
import { isHiDpi } from '@/services/utils'
import { Layer } from '@/stores/map.store.model'
import { OlLayer } from './ol-layer.model'
import { getOlcsExtent, proxyWmsUrl, remoteProxyWms } from './ol-layer.utils'
import { getOlcsExtent } from './ol-layer.utils'

class OlLayerWmsHelper {
createOlLayer(layer: Layer): OlLayer /* Returns: ImageLayer<ImageWMS> */ {
const { name, layers, imageType, url, id } = layer
const olSource = new ImageWMS({
url: url || proxyWmsUrl,
url: url || proxyUrlHelper.wmsProxyUrl,
hidpi: isHiDpi(),
serverType: 'mapserver',
params: {
FORMAT: imageType,
LAYERS: layers,
},
...((url !== undefined && url !== null) || remoteProxyWms
...((url !== undefined && url !== null) || proxyUrlHelper.remoteProxyUrl
? { crossOrigin: 'anonymous' }
: {}),
})
Expand Down
3 changes: 0 additions & 3 deletions src/services/ol-layer/ol-layer.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import {
PROJECTION_WGS84,
} from '@/composables/map/map.composable'

export const proxyWmsUrl = 'https://map.geoportail.lu/ogcproxywms'
export const remoteProxyWms = 'https://map.geoportail.lu/httpsproxy'

export function getOlcsExtent() {
return transformExtent(
[5.31, 49.38, 6.64, 50.21],
Expand Down
23 changes: 23 additions & 0 deletions src/services/proxyurl/proxyurl.helper.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { proxyUrlHelper } from '@/services/proxyurl/proxyurl.helper'

describe('proxyUrlHelper', () => {
beforeEach(() => {
proxyUrlHelper.init_v3('someWmsProxyUrl', 'someRemoteProxyUrl')
})
afterEach(() => {
vi.restoreAllMocks()
})

it('initialize with the right values', () => {
expect(proxyUrlHelper.wmsProxyUrl).toEqual('someWmsProxyUrl')
expect(proxyUrlHelper.remoteProxyUrl).toEqual('someRemoteProxyUrl')
})

describe('#getProxyfiedUrl', () => {
it('returns the url proxified and html encoded', () => {
expect(proxyUrlHelper.getProxyfiedUrl('my=url&32b')).toEqual(
'someRemoteProxyUrl?url=my%3Durl%2632b'
)
})
})
})
77 changes: 77 additions & 0 deletions src/services/proxyurl/proxyurl.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const FORCE_USE_PROXY = import.meta.env.VITE_USE_PROXYURL === 'true'
const WMS_PROXY_URL = import.meta.env.VITE_PROXYURL_WMS
const REMOTE_PROXY_URL = import.meta.env.VITE_PROXYURL_REMOTE

/**
* A helper to get a proxyfied url from a given url (if needed).
* Use deprecated function `ProxyUrlHelper.init_v3()` in legacy project to configure `wmsProxyUrl` and `remoteProxyUrl`.
*/
class ProxyUrlHelper {
private _wmsProxyUrl = WMS_PROXY_URL
private _remoteProxyUrl = REMOTE_PROXY_URL

public get wmsProxyUrl() {
if (this._wmsProxyUrl === undefined) {
console.warn('Warning: proxyWmsUrl is not set.')
}
return this._wmsProxyUrl
}

public get remoteProxyUrl() {
if (this._remoteProxyUrl === undefined) {
console.warn('Warning: remoteProxy is not set.')
}
return this._remoteProxyUrl
}

/**
* Returns the url proxified, if `FORCE_USE_PROXY`, or if current protocol is `https` and url is `http`.
* Don't proxyfy if `httpsproxy` is given in the url.
*
* @param url The url to be proxyfied
* @returns The url proxyfied (if needed)
*/
getProxyfiedUrl(url: string) {
if (url.indexOf('httpsproxy') > 0) {
return url
}

if (
FORCE_USE_PROXY ||
(window.location.protocol === 'https:' &&
url.toLowerCase().indexOf('http:') === 0)
) {
return this.remoteProxyUrl + '?url=' + encodeURIComponent(url)
}

return url
}

/**
* Use this function in v3 to configure ProxyHelper's urls.
*
* @param wmsProxyUrl Proxy url to be used for WMS layers
* @param remoteProxyUrl Remote url to be used for manually added remote layers
*
* @deprecated use env var instead (this function is meant to be removed when v4 is fully operational)
*/
init_v3(wmsProxyUrl?: string, remoteProxyUrl?: string) {
if (wmsProxyUrl) {
this._wmsProxyUrl = wmsProxyUrl
}

if (remoteProxyUrl) {
this._remoteProxyUrl = remoteProxyUrl
}

if (import.meta.env.MODE === 'dev') {
console.warn(
'Deprecated: ProxyUrlHelper.init_v3() is meant to be removed when v4 is fully operational'
)
}
}
}

export const proxyUrlHelper = new ProxyUrlHelper()

export default proxyUrlHelper
25 changes: 18 additions & 7 deletions src/services/remote-layers/remote-layers.mapper.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import { createPinia, setActivePinia } from 'pinia'
import { LayerImageType } from '@/stores/map.store.model'
import { RemoteLayer } from './remote-layers.model'
import {
remoteLayersToLayerTreeMapper,
remoteLayerIdtoLayer,
} from './remote-layers.mapper'
import { createPinia, setActivePinia } from 'pinia'
import { LayerImageType } from '@/stores/map.store.model'
import { remoteLayersService } from './remote-layers.service'
import { LayerTreeNodeModel } from '@/components/layer-tree/layer-tree.model'

describe('remoteLayersToLayerTreeMapper', () => {
beforeEach(() => {
vi.mock('@/services/proxyurl/proxyurl.helper', () => {
return {
proxyUrlHelper: {
getProxyfiedUrl: (url: string) => `myproxifiedurl=${url}`,
},
}
})
})

afterEach(() => {
vi.restoreAllMocks()
})

describe('map WMS layers to tree (including sort)', () => {
let layerTree
let layerTree: LayerTreeNodeModel
const remoteWmsLayers: RemoteLayer[] = [
{
name: 'RootLayer',
Expand Down Expand Up @@ -150,9 +164,6 @@ describe('remoteLayersToLayerTreeMapper', () => {
})

describe('#remoteLayerIdtoLayer using #remoteLayerToLayer', () => {
vi.spyOn(remoteLayersService, 'getProxyfiedUrl').mockImplementation(
url => `myproxifiedurl=${url}`
)
describe('WMS', () => {
const wmsLayer = remoteLayerIdtoLayer('WMS||http://example.com||Layer1')
it('should convert a remote WMS layer id to a layer object', () => {
Expand Down
5 changes: 3 additions & 2 deletions src/services/remote-layers/remote-layers.mapper.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { proxyUrlHelper } from '@/services/proxyurl/proxyurl.helper'
import { useMapStore } from '@/stores/map.store'
import { Layer, LayerId, LayerImageType } from '@/stores/map.store.model'
import { LayerTreeNodeModel } from '@/components/layer-tree/layer-tree.model'

import { RemoteLayer, REMOTE_SERVICE_TYPE } from './remote-layers.model'
import { remoteLayersService } from './remote-layers.service'

function sortLayerTreeNoChildrenFirst(a: RemoteLayer, b: RemoteLayer) {
if ((a.children && !b.children) || b.children?.length === 0) {
Expand Down Expand Up @@ -43,7 +44,7 @@ export function remoteLayerIdtoLayer(layerId: string) {

return remoteLayerToLayer({
id,
url: remoteLayersService.getProxyfiedUrl(url),
url: proxyUrlHelper.getProxyfiedUrl(url),
remoteLayer: { name, type } as RemoteLayer,
})
}
Expand Down
24 changes: 3 additions & 21 deletions src/services/remote-layers/remote-layers.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import {
} from './remote-layers.model'
import { LayerId } from '@/stores/map.store.model'
import { WmtsEndpoint } from '@/services/remote-layers/wmts.endpoint'
import { remoteProxyWms } from '@/services/ol-layer/ol-layer.utils'

const forceUseProxy = true
import { proxyUrlHelper } from '@/services/proxyurl/proxyurl.helper'

export class RemoteLayersService {
public async getRemoteEndpoint(
Expand All @@ -26,27 +24,11 @@ export class RemoteLayersService {
}

public getWmsEndpoint(url: string): OgcClientWmsEndpoint {
return new WmsEndpoint(this.getProxyfiedUrl(url))
return new WmsEndpoint(proxyUrlHelper.getProxyfiedUrl(url))
}

public getWmtsEndpoint(url: string): WmtsEndpoint {
return new WmtsEndpoint(this.getProxyfiedUrl(url))
}

public getProxyfiedUrl(url: string) {
if (url.indexOf('httpsproxy') > 0) {
return url
}

if (
forceUseProxy ||
(window.location.protocol === 'https:' &&
url.toLowerCase().indexOf('http:') === 0)
) {
return remoteProxyWms + '?url=' + encodeURIComponent(url)
}

return url
return new WmtsEndpoint(proxyUrlHelper.getProxyfiedUrl(url))
}

async fetchRemoteWmsEndpoint(): Promise<RemoteWmsEndpointModel[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ vi.mock('@/composables/themes/themes.composable', () => ({
}))

describe('StorageLayerMapper', () => {
beforeEach(() => {
vi.mock('@/services/proxyurl/proxyurl.helper', () => {
return {
proxyUrlHelper: {
getProxyfiedUrl: (url: string) => `myproxifiedurl=${url}`,
},
}
})
})

afterEach(() => {
vi.restoreAllMocks()
})
Expand Down Expand Up @@ -154,7 +164,7 @@ describe('StorageLayerMapper', () => {
imageType: 'image/png',
opacity: 1,
previousOpacity: 1,
url: 'https://map.geoportail.lu/httpsproxy?url=www.mysuperserver.com%2Fmytiles',
url: 'myproxifiedurl=www.mysuperserver.com/mytiles',
currentTimeMinValue: undefined,
},
])
Expand Down
Loading