diff --git a/api/src/paths/proxy/openmaps.ts b/api/src/paths/proxy/openmaps.ts new file mode 100644 index 000000000..69318e8e0 --- /dev/null +++ b/api/src/paths/proxy/openmaps.ts @@ -0,0 +1,88 @@ +import { RequestHandler } from 'express'; +import { Operation } from 'express-openapi'; +import { ALL_ROLES, SECURITY_ON } from 'constants/misc'; +import { getLogger } from 'utils/logger'; +import { InvasivesRequest } from 'utils/auth-utils'; +const https = require('https'); + +const defaultLog = getLogger('proxy'); + +const GET: Operation = [getOpenMapsWMSTiles()]; + +GET.apiDoc = { + description: 'Proxy requests to a BCGW WMS endpoint', + tags: ['proxy'], + parameters: [ + { + name: 'url', + in: 'query', + required: true, + type: 'string', + description: 'The target WMS URL to proxy' + } + ], + responses: { + 200: { + description: 'Successful response', + schema: { + type: 'string' + } + }, + 400: { + description: 'Invalid request' + }, + 500: { + description: 'Internal server error' + }, + 401: { + $ref: '#/components/responses/401' + }, + 503: { + $ref: '#/components/responses/503' + }, + default: { + $ref: '#/components/responses/default' + } + } +}; + +/** + * Proxy request to Openmaps from mobile, redirect the response back to the client + * + * @return {RequestHandler} + */ +function getOpenMapsWMSTiles(): RequestHandler { + return async (req, res, next) => { + const targetUrl = req.query.url; + + if (!targetUrl) { + return res.status(400).json({ + message: 'Missing URL parameter', + request: req.body, + namespace: 'openmaps/url={url}', + code: 400 + }); + } + + https + .get(targetUrl, (apiRes) => { + if (apiRes.statusCode !== 200) { + console.error(`Failed to fetch data: ${apiRes.statusMessage}`); + return res.status(apiRes.statusCode).send(`Error fetching data: ${apiRes.statusMessage}`); + } + + // Pass through headers from the OpenMaps API response + res.setHeader('Content-Type', apiRes.headers['content-type']); + res.setHeader('Cache-Control', apiRes.headers['cache-control'] || 'no-cache'); + + // Pipe the API response directly to the client + apiRes.pipe(res); + }) + .on('error', (err) => { + console.error('Request error:', err); + res.status(500).send('Internal Server Error'); + }); + }; +} + +export { GET }; diff --git a/app/capacitor.config.ts b/app/capacitor.config.ts index 4a0bbfb04..80109c2b6 100644 --- a/app/capacitor.config.ts +++ b/app/capacitor.config.ts @@ -17,7 +17,7 @@ const config: CapacitorConfig = { enabled: false }, CapacitorHttp: { - enabled: true + enabled: false }, CapacitorSQLite: { iosDatabaseLocation: 'Library/InvasivesDatabase' diff --git a/app/src/UI/Map2/LayerPicker/LpLayers/LpLayers.tsx b/app/src/UI/Map2/LayerPicker/LpLayers/LpLayers.tsx index e9136c78d..3efbdda8c 100644 --- a/app/src/UI/Map2/LayerPicker/LpLayers/LpLayers.tsx +++ b/app/src/UI/Map2/LayerPicker/LpLayers/LpLayers.tsx @@ -38,6 +38,7 @@ const LpLayers = () => { const WmsLayers = useSelector((state) => state.Map?.simplePickerLayers2); const KmlLayers = useSelector((state) => state.Map?.serverBoundaries); const drawnLayers = useSelector((state) => state.Map?.clientBoundaries); + const isAuth = useSelector((state: any) => state.Auth?.authenticated); return (
@@ -45,7 +46,7 @@ const LpLayers = () => { DataBC Layers
- {WmsLayers?.length > 0 && connectedToNetwork ? ( + {WmsLayers?.length > 0 && connectedToNetwork && isAuth ? (
    {WmsLayers.map((layer, index) => ( { maxZoom: 24, zoom: 3, minZoom: 0, - transformRequest: (url) => { + transformRequest: (url, resourceType) => { if (url.includes(api_base)) { return { url, @@ -137,6 +137,16 @@ export const mapInit = (options: MapInitOptions) => { } }; } + + const api_local = 'http://localhost:3002'; + // to make bcgw layers work on mobile + if (MOBILE && url.includes('openmaps.gov.bc.ca/geo/ows')) { + const proxyUrl = `${api_local}/api/proxy/openmaps?url=${encodeURIComponent(url)}`; + return { + url: proxyUrl + }; + } + return { url };