From a594cb5c174f99e8cc35f37fd46ea44d27ab3129 Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Mon, 21 Oct 2024 17:34:41 +0800 Subject: [PATCH 01/16] 1383-add-authorization-header-to-getmap-requests: added axios dependency --- web/twa-vis-platform/code/package.json | 155 +++++++++++++------------ 1 file changed, 78 insertions(+), 77 deletions(-) diff --git a/web/twa-vis-platform/code/package.json b/web/twa-vis-platform/code/package.json index 8a78ff0e171..817c3d8242d 100644 --- a/web/twa-vis-platform/code/package.json +++ b/web/twa-vis-platform/code/package.json @@ -1,79 +1,80 @@ { - "name": "twa-visualisation-platform", - "version": "0.1.0", - "private": true, - "type": "module", - "eslintConfig": { - "extends": "next/core-web-vitals" - }, - "jest": { - "verbose": true - }, - "scripts": { - "dev": "NODE_ENV=development node --env-file='.env.local' server.js", - "dev-docker": "NODE_ENV=development node server.js", - "build": "next build", - "start": "NODE_ENV=production node --env-file='.env.local' server.js", - "start-docker": "NODE_ENV=production node server.js", - "lint": "next lint", - "test": "jest" - }, - "dependencies": { - "9": "^0.0.1", - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "@mui/icons-material": "^6.1.1", - "@mui/material": "^6.1.1", - "@reduxjs/toolkit": "^2.2.7", - "@types/markdown-it": "^14.1.2", - "@types/node": "^22.7.2", - "@types/react": "^18.3.9", - "@types/react-modal": "^3.16.3", - "@typescript-eslint/eslint-plugin": "^8.7.0", - "@typescript-eslint/parser": "8.7.0", - "chart.js": "^4.4.4", - "chartjs-adapter-moment": "^1.0.1", - "connect-redis": "^7.1.1", - "express": "^4.21.0", - "express-session": "^1.18.0", - "framer-motion": "^11.8.0", - "github-markdown-css": "^5.7.0", - "gray-matter": "^4.0.3", - "keycloak-connect": "^25.0.6", - "mapbox-gl": "3.6.0", - "markdown-it": "^14.1.0", - "moment": "^2.30.1", - "next": "^14.2.13", - "react": "^18.3.1", - "react-confetti": "^6.1.0", - "react-dom": "^18.3.1", - "react-hook-form": "^7.53.0", - "react-inlinesvg": "^4.1.3", - "react-konami-code": "^2.3.0", - "react-map-gl": "^7.1.7", - "react-markdown": "^9.0.1", - "react-modal": "^3.16.1", - "react-redux": "^9.1.2", - "react-router-dom": "^6.26.2", - "react-toastify": "^10.0.5", - "redis": "^4.7.0", - "redux": "^5.0.1", - "redux-persist": "^6.0.0", - "typescript": "^5.6.2" - }, - "devDependencies": { - "@types/express": "^5.0.0", - "@types/jest": "^29.5.13", - "@types/mapbox": "^1.6.45", - "@types/mapbox-gl": "^3.4.0", - "@types/react-dom": "^18.3.0", - "eslint": "^8.57.1", - "eslint-config-next": "^14.2.13", - "eslint-plugin-react": "^7.36.1", - "fs": "0.0.1-security", - "jest": "^29.7.0", - "ts-jest": "^29.2.5", - "ts-typed-json": "^0.3.2" - }, - "packageManager": "pnpm@9.6.0+sha512.38dc6fba8dba35b39340b9700112c2fe1e12f10b17134715a4aa98ccf7bb035e76fd981cf0bb384dfa98f8d6af5481c2bef2f4266a24bfa20c34eb7147ce0b5e" + "name": "twa-visualisation-platform", + "version": "0.1.0", + "private": true, + "type": "module", + "eslintConfig": { + "extends": "next/core-web-vitals" + }, + "jest": { + "verbose": true + }, + "scripts": { + "dev": "NODE_ENV=development node --env-file='.env.local' server.js", + "dev-docker": "NODE_ENV=development node server.js", + "build": "next build", + "start": "NODE_ENV=production node --env-file='.env.local' server.js", + "start-docker": "NODE_ENV=production node server.js", + "lint": "next lint", + "test": "jest" + }, + "dependencies": { + "9": "^0.0.1", + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^6.1.1", + "@mui/material": "^6.1.1", + "@reduxjs/toolkit": "^2.2.7", + "@types/markdown-it": "^14.1.2", + "@types/node": "^22.7.2", + "@types/react": "^18.3.9", + "@types/react-modal": "^3.16.3", + "@typescript-eslint/eslint-plugin": "^8.7.0", + "@typescript-eslint/parser": "8.7.0", + "axios": "^1.7.7", + "chart.js": "^4.4.4", + "chartjs-adapter-moment": "^1.0.1", + "connect-redis": "^7.1.1", + "express": "^4.21.0", + "express-session": "^1.18.0", + "framer-motion": "^11.8.0", + "github-markdown-css": "^5.7.0", + "gray-matter": "^4.0.3", + "keycloak-connect": "^25.0.6", + "mapbox-gl": "3.6.0", + "markdown-it": "^14.1.0", + "moment": "^2.30.1", + "next": "^14.2.13", + "react": "^18.3.1", + "react-confetti": "^6.1.0", + "react-dom": "^18.3.1", + "react-hook-form": "^7.53.0", + "react-inlinesvg": "^4.1.3", + "react-konami-code": "^2.3.0", + "react-map-gl": "^7.1.7", + "react-markdown": "^9.0.1", + "react-modal": "^3.16.1", + "react-redux": "^9.1.2", + "react-router-dom": "^6.26.2", + "react-toastify": "^10.0.5", + "redis": "^4.7.0", + "redux": "^5.0.1", + "redux-persist": "^6.0.0", + "typescript": "^5.6.2" + }, + "devDependencies": { + "@types/express": "^5.0.0", + "@types/jest": "^29.5.13", + "@types/mapbox": "^1.6.45", + "@types/mapbox-gl": "^3.4.0", + "@types/react-dom": "^18.3.0", + "eslint": "^8.57.1", + "eslint-config-next": "^14.2.13", + "eslint-plugin-react": "^7.36.1", + "fs": "0.0.1-security", + "jest": "^29.7.0", + "ts-jest": "^29.2.5", + "ts-typed-json": "^0.3.2" + }, + "packageManager": "pnpm@9.6.0+sha512.38dc6fba8dba35b39340b9700112c2fe1e12f10b17134715a4aa98ccf7bb035e76fd981cf0bb384dfa98f8d6af5481c2bef2f4266a24bfa20c34eb7147ce0b5e" } \ No newline at end of file From 6ec55d6c0d31d01ec47da9f58a07afc601a32440 Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Mon, 21 Oct 2024 17:37:42 +0800 Subject: [PATCH 02/16] 1383-add-authorization-header-to-getmap-requests: add Authorization header to GeoServer GetMap requests --- web/twa-vis-platform/code/server.js | 183 +++++++++++------- .../code/src/hooks/useGeoServerProxy.ts | 18 ++ .../code/src/map/mapbox/mapbox-container.tsx | 141 ++++++++------ 3 files changed, 210 insertions(+), 132 deletions(-) create mode 100644 web/twa-vis-platform/code/src/hooks/useGeoServerProxy.ts diff --git a/web/twa-vis-platform/code/server.js b/web/twa-vis-platform/code/server.js index 2500b3b2f5f..ed65676d9d6 100644 --- a/web/twa-vis-platform/code/server.js +++ b/web/twa-vis-platform/code/server.js @@ -20,6 +20,7 @@ import session, { MemoryStore } from 'express-session'; import { createClient } from "redis" import RedisStore from 'connect-redis'; import Keycloak from 'keycloak-connect'; +import axios from 'axios'; const colourReset = "\x1b[0m"; const colourRed = "\x1b[31m"; @@ -46,82 +47,120 @@ let store; // Prepare the Next.js application and then start the Express server app.prepare().then(() => { - const server = express(); - - if (keycloakEnabled) { // do keycloak auth stuff if env var is set - console.log('the following pages require keycloak authentication', process.env.PROTECTED_PAGES ? colourYellow : colourRed, process.env.PROTECTED_PAGES, colourReset) - console.log('the following pages require the', process.env.ROLE ? colourYellow : colourRed, process.env.ROLE, colourReset, 'role: ', process.env.ROLE_PROTECTED_PAGES ? colourYellow : colourRed, process.env.ROLE_PROTECTED_PAGES, colourReset) - - server.set('trust proxy', true); // the client’s IP address is understood as the left-most entry in the X-Forwarded-For header. - - if (!dev) { - let redisClient; - console.log(`development mode is:`, colourGreen, dev, colourReset, `-> connecting to redis session store at`, colourGreen, `${redisHost}:${redisPort}`, colourReset); - try { - redisClient = createClient({ - socket: { - host: redisHost, - port: redisPort - } + const server = express(); + + if (keycloakEnabled) { // do keycloak auth stuff if env var is set + console.log('the following pages require keycloak authentication', process.env.PROTECTED_PAGES ? colourYellow : colourRed, process.env.PROTECTED_PAGES, colourReset) + console.log('the following pages require the', process.env.ROLE ? colourYellow : colourRed, process.env.ROLE, colourReset, 'role: ', process.env.ROLE_PROTECTED_PAGES ? colourYellow : colourRed, process.env.ROLE_PROTECTED_PAGES, colourReset) + + server.set('trust proxy', true); // the client’s IP address is understood as the left-most entry in the X-Forwarded-For header. + + if (!dev) { + let redisClient; + console.log(`development mode is:`, colourGreen, dev, colourReset, `-> connecting to redis session store at`, colourGreen, `${redisHost}:${redisPort}`, colourReset); + try { + redisClient = createClient({ + socket: { + host: redisHost, + port: redisPort + } + }); + } catch (error) { + console.log('Error while creating Redis Client, please ensure that Redis is running and the host is specified as an environment variable if this viz app is in a Docker container'); + console.error(error); + } + redisClient.connect().catch('Error while creating Redis Client, please ensure that Redis is running and the host is specified as an environment variable if this viz app is in a Docker container', console.error); + store = new RedisStore({ + client: redisClient, + prefix: "redis", + ttl: undefined, + }); + } else { + store = new MemoryStore(); // use in-memory store for session data in dev mode + console.log(`development mode is:`, dev ? colourYellow : colourRed, dev, colourReset, `-> using in-memory session store (express-session MemoryStore())`); + } + + server.use( + session({ + secret: 'login', + resave: false, + saveUninitialized: true, + store: store, + }) + ); + + const keycloak = new Keycloak({ store: store }); + server.use(keycloak.middleware()); + + server.get('/api/userinfo', keycloak.protect(), (req, res) => { + const { preferred_username: userName, given_name: firstName, family_name: lastName, name: fullName, realm_access: { roles }, resource_access: clientRoles } = req.kauth.grant.access_token.content; + res.json({ userName, firstName, lastName, fullName, roles, clientRoles }); }); - } catch (error) { - console.log('Error while creating Redis Client, please ensure that Redis is running and the host is specified as an environment variable if this viz app is in a Docker container'); - console.error(error); - } - redisClient.connect().catch('Error while creating Redis Client, please ensure that Redis is running and the host is specified as an environment variable if this viz app is in a Docker container', console.error); - store = new RedisStore({ - client: redisClient, - prefix: "redis", - ttl: undefined, - }); - } else { - store = new MemoryStore(); // use in-memory store for session data in dev mode - console.log(`development mode is:`, dev ? colourYellow : colourRed, dev, colourReset, `-> using in-memory session store (express-session MemoryStore())`); - } - server.use( - session({ - secret: 'login', - resave: false, - saveUninitialized: true, - store: store, - }) - ); - - const keycloak = new Keycloak({ store: store }); - server.use(keycloak.middleware()); - - server.get('/api/userinfo', keycloak.protect(), (req, res) => { - const { preferred_username: userName, given_name: firstName, family_name: lastName, name: fullName, realm_access: { roles }, resource_access: clientRoles } = req.kauth.grant.access_token.content; - res.json({ userName, firstName, lastName, fullName, roles, clientRoles }); - }); + server.get('/logout', (req, res) => { + req.logout(); // Keycloak adapter logout + req.session.destroy(() => { // This destroys the session + res.clearCookie('connect.sid', { path: '/' }); // Clear the session cookie + }); + }); - server.get('/logout', (req, res) => { - req.logout(); // Keycloak adapter logout - req.session.destroy(() => { // This destroys the session - res.clearCookie('connect.sid', { path: '/' }); // Clear the session cookie - }); - }); + const protectedPages = process.env.PROTECTED_PAGES.split(','); + protectedPages.forEach(page => { + server.get(page, keycloak.protect()); + }); + const roleProtectedPages = process.env.ROLE_PROTECTED_PAGES.split(','); + roleProtectedPages.forEach(page => { + server.get(page, keycloak.protect(process.env.ROLE)); + console.log('protecting page', page, 'with role', process.env.ROLE); + }); + + // this is a hack because I cannot figure out why process.env.REACT_APP_USE_GEOSERVER_PROXY is not working on the browser + const useGeoServerProxy = process.env.REACT_APP_USE_GEOSERVER_PROXY === 'true'; + console.log('REACT_APP_USE_GEOSERVER_PROXY is ' + useGeoServerProxy); + server.get('/env/use-geoserver-proxy', (_req, res) => { + res.json({ useGeoServerProxy }); + }) + + if (useGeoServerProxy) { + console.log('GeoServer requests from MapBox will be sent to /geoserver-proxy') + } + + if (useGeoServerProxy) { + server.get('/geoserver-proxy', async (req, res) => { + const targetUrl = req.query.url; + let headers = { ...req.headers }; + + if (req.kauth?.grant) { + headers['Authorization'] = 'Bearer ' + req.kauth.grant.access_token.token; + } + + try { + // Forward the request to the target URL with the modified headers + const response = await axios({ + url: targetUrl, + method: req.method, + headers: headers, + responseType: 'stream', // To stream the response back + }); + + // Pipe the response back to the client + response.data.pipe(res); + } catch (err) { + // most of these errors can probably be ignored + console.error(err); + } + }); + } + } - const protectedPages = process.env.PROTECTED_PAGES.split(','); - protectedPages.forEach(page => { - server.get(page, keycloak.protect()); + // Handle all other requests using Next.js + server.all("*", (req, res) => { + return handle(req, res); }); - const roleProtectedPages = process.env.ROLE_PROTECTED_PAGES.split(','); - roleProtectedPages.forEach(page => { - server.get(page, keycloak.protect(process.env.ROLE)); - console.log('protecting page', page, 'with role', process.env.ROLE); + + // Start listening on the specified port and log server status + server.listen(port, (err) => { + if (err) throw err; + console.log('Running at', colourGreen, `http://localhost:${port}`, colourReset, `development mode is:`, dev ? colourYellow : colourGreen, dev, colourReset); }); - } - - // Handle all other requests using Next.js - server.all("*", (req, res) => { - return handle(req, res); - }); - - // Start listening on the specified port and log server status - server.listen(port, (err) => { - if (err) throw err; - console.log('Running at', colourGreen, `http://localhost:${port}`, colourReset, `development mode is:`, dev ? colourYellow : colourGreen, dev, colourReset); - }); }); \ No newline at end of file diff --git a/web/twa-vis-platform/code/src/hooks/useGeoServerProxy.ts b/web/twa-vis-platform/code/src/hooks/useGeoServerProxy.ts new file mode 100644 index 00000000000..49f071bd0c6 --- /dev/null +++ b/web/twa-vis-platform/code/src/hooks/useGeoServerProxy.ts @@ -0,0 +1,18 @@ +import { useEffect, useState } from 'react'; + +// a fudge because process.env does not work on browser +export function useGeoServerProxy() { + const [useProxy, setUseProxy] = useState(false); + + useEffect(() => { + const fetchProxyValue = async () => { + const response = await fetch('/env/use-geoserver-proxy'); + const data = await response.json(); + setUseProxy(data.useGeoServerProxy); + }; + + fetchProxyValue(); + }, []); + + return { useProxy }; +} \ No newline at end of file diff --git a/web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx b/web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx index c4fc4a57f36..e90ec54f55b 100644 --- a/web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx +++ b/web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx @@ -9,13 +9,14 @@ import React, { useEffect, useRef } from 'react'; import MapEventManager from 'map/map-event-manager'; import { MapSettings } from 'types/settings'; import { getCurrentImageryOption, getDefaultCameraPosition } from 'map/map-helper'; +import { useGeoServerProxy } from 'hooks/useGeoServerProxy'; // Type definition of incoming properties interface MapProperties { - settings: MapSettings; - currentMap: Map; - setMap: React.Dispatch>; - setMapEventManager: React.Dispatch>; + settings: MapSettings; + currentMap: Map; + setMap: React.Dispatch>; + setMapEventManager: React.Dispatch>; } /** @@ -26,72 +27,92 @@ interface MapProperties { * @returns React component for display. */ export default function MapboxMapComponent(props: MapProperties) { - const mapContainer = useRef(null); + const mapContainer = useRef(null); + const { useProxy } = useGeoServerProxy() - // Run when component loaded - useEffect(() => { - initialiseMap(); + // Run when component loaded + useEffect(() => { + initialiseMap(); - return () => { - if (props.currentMap) { - props.currentMap.remove(); // Remove the map instance - props.setMap(null); // Reset the map ref - } - }; - }, []); + return () => { + if (props.currentMap) { + props.currentMap.remove(); // Remove the map instance + props.setMap(null); // Reset the map ref + } + }; + }, [useProxy]); - // Initialise the map object - const initialiseMap = async () => { - props.currentMap?.remove(); + // Initialise the map object + const initialiseMap = async () => { + props.currentMap?.remove(); - const response = await fetch(("./api/map/settings"), { - method: "GET", - headers: { "Content-Type": "application/json" }, - }); - const respJson = await response.json(); - // Set credentials - mapboxgl.accessToken = respJson.token; + const response = await fetch(("./api/map/settings"), { + method: "GET", + headers: { "Content-Type": "application/json" }, + }); + const respJson = await response.json(); + // Set credentials + mapboxgl.accessToken = respJson.token; - // Get default camera position - const defaultPosition = getDefaultCameraPosition(props.settings.camera); - let styleObject = getCurrentImageryOption(props.settings.imagery); + // Get default camera position + const defaultPosition = getDefaultCameraPosition(props.settings.camera); + let styleObject = getCurrentImageryOption(props.settings.imagery); - const map: Map = new mapboxgl.Map({ - container: mapContainer.current, - style: styleObject.url, - center: defaultPosition["center"], - zoom: defaultPosition["zoom"], - bearing: defaultPosition["bearing"], - pitch: defaultPosition["pitch"], - }); + const map: Map = new mapboxgl.Map({ + container: mapContainer.current, + style: styleObject.url, + center: defaultPosition["center"], + zoom: defaultPosition["zoom"], + bearing: defaultPosition["bearing"], + pitch: defaultPosition["pitch"], + transformRequest: (url) => { + if (useProxy) { + try { + const urlObject = new URL(url); + const params = new URLSearchParams(urlObject.search); + if (params.get('request') === 'GetMap') { + // not sure if this will work across all conditions + const serverUrl = `${window.location.protocol}//${window.location.host}`; + const proxyUrl = `${serverUrl}/geoserver-proxy?url=${encodeURIComponent(url)}`; + console.log('proxyUrl is ' + proxyUrl); + return { + url: proxyUrl + } + } + } catch { } + } else { + return { url: url } + } + } + }); - map.addControl(new mapboxgl.ScaleControl() as mapboxgl.IControl, "bottom-right"); - map.addControl(new mapboxgl.NavigationControl(), "bottom-right"); + map.addControl(new mapboxgl.ScaleControl() as mapboxgl.IControl, "bottom-right"); + map.addControl(new mapboxgl.NavigationControl(), "bottom-right"); - console.info("Initialised a new Mapbox map object."); + console.info("Initialised a new Mapbox map object."); - map.on("style.load", function () { - // Update time if using new v3 standard style - styleObject = getCurrentImageryOption(props.settings.imagery); - if (styleObject.time != null) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (map as any).setConfigProperty( - "basemap", - "lightPreset", - styleObject.time - ); - } - // Map is only settable after the styles have loaded - props.setMap(map); - props.setMapEventManager(new MapEventManager(map)); - }); - }; + map.on("style.load", function () { + // Update time if using new v3 standard style + styleObject = getCurrentImageryOption(props.settings.imagery); + if (styleObject.time != null) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (map as any).setConfigProperty( + "basemap", + "lightPreset", + styleObject.time + ); + } + // Map is only settable after the styles have loaded + props.setMap(map); + props.setMapEventManager(new MapEventManager(map)); + }); + }; - return ( -
- {/* Map will be generated here. */} -
- ); + return ( +
+ {/* Map will be generated here. */} +
+ ); } MapboxMapComponent.displayName = "MapboxMapComponent"; \ No newline at end of file From 27579ba778692212df1c5224120f90c54d3b17ea Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Mon, 21 Oct 2024 17:39:54 +0800 Subject: [PATCH 03/16] 1383-add-authorization-header-to-getmap-requests: added REACT_APP_USE_GEOSERVER_PROXY variable in docker compose files --- web/twa-vis-platform/docker-compose.dev.yml | 1 + web/twa-vis-platform/docker-compose.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/web/twa-vis-platform/docker-compose.dev.yml b/web/twa-vis-platform/docker-compose.dev.yml index ce6b978e076..8312d361b36 100644 --- a/web/twa-vis-platform/docker-compose.dev.yml +++ b/web/twa-vis-platform/docker-compose.dev.yml @@ -18,6 +18,7 @@ services: PROTECTED_PAGES: / ## pages that a user must be logged in to see ROLE_PROTECTED_PAGES: /add/* ## pages that require a user to have a given REALM or CLIENT role ROLE: protected ## the role required for the above list + REACT_APP_USE_GEOSERVER_PROXY: false REDIS_HOST: host.docker.internal secrets: diff --git a/web/twa-vis-platform/docker-compose.yml b/web/twa-vis-platform/docker-compose.yml index 3297fbfdc45..4759b705c2b 100644 --- a/web/twa-vis-platform/docker-compose.yml +++ b/web/twa-vis-platform/docker-compose.yml @@ -12,6 +12,7 @@ services: PROTECTED_PAGES: /page,/otherpage ## pages that a user must be logged in to see ROLE_PROTECTED_PAGES: /protected/page/ ## pages that require a user to have a given REALM or CLIENT role ROLE: twa-test:protected ## the role required for the above list + REACT_APP_USE_GEOSERVER_PROXY: false REDIS_HOST: host.docker.internal secrets: From 0f500d19fadfd6d0d6197509057980700495c381 Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Mon, 21 Oct 2024 17:40:46 +0800 Subject: [PATCH 04/16] 1383-add-authorization-header-to-getmap-requests: updated version number --- web/twa-vis-platform/resources/CHANGELOG.md | 6 ++++++ web/twa-vis-platform/resources/VERSION | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/web/twa-vis-platform/resources/CHANGELOG.md b/web/twa-vis-platform/resources/CHANGELOG.md index fbb8c56d506..d415b25043e 100644 --- a/web/twa-vis-platform/resources/CHANGELOG.md +++ b/web/twa-vis-platform/resources/CHANGELOG.md @@ -3,6 +3,12 @@ [//]: # (Note that version headers need to start with "## " characters to be picked up by some automated scripts) +## 5.8.0 + +### Feature + +* Added ability to add the 'Authorization' header to WMS requests + ## 5.7.0 ### Bug Fixes diff --git a/web/twa-vis-platform/resources/VERSION b/web/twa-vis-platform/resources/VERSION index 3b867ccd76c..edb1d397cf2 100644 --- a/web/twa-vis-platform/resources/VERSION +++ b/web/twa-vis-platform/resources/VERSION @@ -1 +1 @@ -5.7.0 \ No newline at end of file +5.8.0 \ No newline at end of file From 93f4bb7542612e0b57cab4b35c44ffbe944c1159 Mon Sep 17 00:00:00 2001 From: Kok Foong Lee <71323448+kok-foong@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:55:02 +0800 Subject: [PATCH 05/16] 1383-add-authorization-header-to-getmap-requests: Update CHANGELOG.md --- web/twa-vis-platform/resources/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/twa-vis-platform/resources/CHANGELOG.md b/web/twa-vis-platform/resources/CHANGELOG.md index d415b25043e..bc2e4df288e 100644 --- a/web/twa-vis-platform/resources/CHANGELOG.md +++ b/web/twa-vis-platform/resources/CHANGELOG.md @@ -7,7 +7,7 @@ ### Feature -* Added ability to add the 'Authorization' header to WMS requests +* Added ability to add the 'Authorization' header to GetMap requests ## 5.7.0 From 1009b066b56f1dd6507e061bbd441539123c9abb Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Mon, 21 Oct 2024 18:08:26 +0800 Subject: [PATCH 06/16] 1383-add-authorization-header-to-getmap-requests: removed logging added during development --- web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx b/web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx index e90ec54f55b..8b3f6a86a3d 100644 --- a/web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx +++ b/web/twa-vis-platform/code/src/map/mapbox/mapbox-container.tsx @@ -74,7 +74,6 @@ export default function MapboxMapComponent(props: MapProperties) { // not sure if this will work across all conditions const serverUrl = `${window.location.protocol}//${window.location.host}`; const proxyUrl = `${serverUrl}/geoserver-proxy?url=${encodeURIComponent(url)}`; - console.log('proxyUrl is ' + proxyUrl); return { url: proxyUrl } From 1c6972b1df40afdcd962f1bdc16abd1ce5039cc3 Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Fri, 22 Nov 2024 13:36:13 +0800 Subject: [PATCH 07/16] 1383-add-authorization-header-to-getmap-requests: whitespace changes only --- .../src/ui/map/mapbox/mapbox-container.tsx | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx b/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx index 095f9980088..024c1e25fb8 100644 --- a/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx +++ b/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx @@ -13,10 +13,10 @@ import { useGeoServerProxy } from 'hooks/useGeoServerProxy'; // Type definition of incoming properties interface MapProperties { currentMap: Map; - styles: string; + styles: string; setMap: React.Dispatch>; - defaultPosition: CameraPosition; - imageryOption?: ImageryOption; + defaultPosition: CameraPosition; + imageryOption?: ImageryOption; } /** @@ -50,13 +50,13 @@ export default function MapboxMapComponent(props: MapProperties) { const initialiseMap = async () => { props.currentMap?.remove(); - const defaultImagery: ImageryOption = props.imageryOption ?? { - "name": "Standard (Night)", - "url": "mapbox://styles/mapbox/standard", - "time": "dusk" - }; + const defaultImagery: ImageryOption = props.imageryOption ?? { + "name": "Standard (Night)", + "url": "mapbox://styles/mapbox/standard", + "time": "dusk" + }; - const response = await fetch((Apis.MAP_SETTINGS), { + const response = await fetch((Apis.MAP_SETTINGS), { method: "GET", headers: { "Content-Type": "application/json" }, }); @@ -66,11 +66,11 @@ export default function MapboxMapComponent(props: MapProperties) { const map: Map = new mapboxgl.Map({ container: mapContainer.current, - style: defaultImagery.url, - center: props.defaultPosition.center, - zoom: props.defaultPosition.zoom, - bearing: props.defaultPosition.bearing, - pitch: props.defaultPosition.pitch, + style: defaultImagery.url, + center: props.defaultPosition.center, + zoom: props.defaultPosition.zoom, + bearing: props.defaultPosition.bearing, + pitch: props.defaultPosition.pitch, transformRequest: (url) => { if (useProxy) { try { @@ -98,12 +98,12 @@ export default function MapboxMapComponent(props: MapProperties) { map.on("style.load", function () { // Update time if using new v3 standard style - if (defaultImagery.time != null) { + if (defaultImagery.time != null) { // eslint-disable-next-line @typescript-eslint/no-explicit-any (map as any).setConfigProperty( "basemap", "lightPreset", - defaultImagery.time + defaultImagery.time ); } // Map is only settable after the styles have loaded @@ -112,7 +112,7 @@ export default function MapboxMapComponent(props: MapProperties) { }; return ( -
+
{/* Map will be generated here. */}
); From a5f1f2323ea5b1f43da05a45ff57b56d72e8c1cc Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Tue, 26 Nov 2024 18:02:37 +0800 Subject: [PATCH 08/16] 1383-add-authorization-header-to-getmap-requests: remove hook --- web/twa-vis-platform/code/next.config.js | 37 ++++++++++--------- web/twa-vis-platform/code/pnpm-lock.yaml | 24 +++++------- web/twa-vis-platform/code/server.js | 18 ++++----- .../code/src/hooks/useGeoServerProxy.ts | 18 --------- .../src/ui/map/mapbox/mapbox-container.tsx | 19 ++++------ 5 files changed, 44 insertions(+), 72 deletions(-) delete mode 100644 web/twa-vis-platform/code/src/hooks/useGeoServerProxy.ts diff --git a/web/twa-vis-platform/code/next.config.js b/web/twa-vis-platform/code/next.config.js index f5f6e18906c..c7ad26732c9 100644 --- a/web/twa-vis-platform/code/next.config.js +++ b/web/twa-vis-platform/code/next.config.js @@ -1,26 +1,27 @@ /** - Next.js can be configured through a next.config.js file in the - root of your project directory (for example, by package.json). + Next.js can be configured through a next.config.js file in the + root of your project directory (for example, by package.json). - next.config.js is a regular Node.js module, not a JSON file. - It gets used by the Next.js server and build phases, and it's - not included in the browser build. + next.config.js is a regular Node.js module, not a JSON file. + It gets used by the Next.js server and build phases, and it's + not included in the browser build. **/ const nextConfig = { - reactStrictMode: true, - assetPrefix: process.env.ASSET_PREFIX ?? "", - compiler: { removeConsole: false }, - images: { - loader: 'custom', - loaderFile: './image-loader.js', - }, - env: { - KEYCLOAK: process.env.KEYCLOAK ?? "false", - ASSET_PREFIX: process.env.ASSET_PREFIX ?? "", - MAPBOX_USER: process.env.MAPBOX_USER, - MAPBOX_API_KEY: process.env.MAPBOX_API_KEY, - } + reactStrictMode: true, + assetPrefix: process.env.ASSET_PREFIX ?? "", + compiler: { removeConsole: false }, + images: { + loader: 'custom', + loaderFile: './image-loader.js', + }, + env: { + KEYCLOAK: process.env.KEYCLOAK ?? "false", + ASSET_PREFIX: process.env.ASSET_PREFIX ?? "", + MAPBOX_USER: process.env.MAPBOX_USER, + MAPBOX_API_KEY: process.env.MAPBOX_API_KEY, + REACT_APP_USE_GEOSERVER_PROXY: process.env.REACT_APP_USE_GEOSERVER_PROXY, + } }; diff --git a/web/twa-vis-platform/code/pnpm-lock.yaml b/web/twa-vis-platform/code/pnpm-lock.yaml index f956cb00c40..7db28c2800b 100644 --- a/web/twa-vis-platform/code/pnpm-lock.yaml +++ b/web/twa-vis-platform/code/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: '@typescript-eslint/parser': specifier: 8.14.0 version: 8.14.0(eslint@8.57.1)(typescript@5.6.3) + axios: + specifier: ^1.7.7 + version: 1.7.7 chart.js: specifier: ^4.4.6 version: 4.4.6 @@ -5055,8 +5058,7 @@ snapshots: async@3.2.6: {} - asynckit@0.4.0: - optional: true + asynckit@0.4.0: {} available-typed-arrays@1.0.7: dependencies: @@ -5071,7 +5073,6 @@ snapshots: proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - optional: true axobject-query@4.1.0: {} @@ -5299,7 +5300,6 @@ snapshots: combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - optional: true comma-separated-tokens@2.0.3: {} @@ -5434,8 +5434,7 @@ snapshots: esprima: 4.0.1 optional: true - delayed-stream@1.0.0: - optional: true + delayed-stream@1.0.0: {} depd@2.0.0: {} @@ -5656,7 +5655,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -5669,7 +5668,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -5691,7 +5690,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -5996,8 +5995,7 @@ snapshots: flatted@3.3.2: {} - follow-redirects@1.15.9: - optional: true + follow-redirects@1.15.9: {} for-each@0.3.3: dependencies: @@ -6013,7 +6011,6 @@ snapshots: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - optional: true forwarded@0.2.0: {} @@ -7511,8 +7508,7 @@ snapshots: - supports-color optional: true - proxy-from-env@1.1.0: - optional: true + proxy-from-env@1.1.0: {} pump@3.0.2: dependencies: diff --git a/web/twa-vis-platform/code/server.js b/web/twa-vis-platform/code/server.js index 47550cb30f5..217dcc8fba2 100644 --- a/web/twa-vis-platform/code/server.js +++ b/web/twa-vis-platform/code/server.js @@ -52,14 +52,14 @@ app.prepare().then(() => { const server = express(); if (keycloakEnabled) { // do keycloak auth stuff if env var is set - console.info('the following pages require keycloak authentication', process.env.PROTECTED_PAGES ? colourYellow : colourRed, process.env.PROTECTED_PAGES, colourReset) - console.info('the following pages require the', process.env.ROLE ? colourYellow : colourRed, process.env.ROLE, colourReset, 'role: ', process.env.ROLE_PROTECTED_PAGES ? colourYellow : colourRed, process.env.ROLE_PROTECTED_PAGES, colourReset) + console.info('the following pages require keycloak authentication', process.env.PROTECTED_PAGES ? colourYellow : colourRed, process.env.PROTECTED_PAGES, colourReset) + console.info('the following pages require the', process.env.ROLE ? colourYellow : colourRed, process.env.ROLE, colourReset, 'role: ', process.env.ROLE_PROTECTED_PAGES ? colourYellow : colourRed, process.env.ROLE_PROTECTED_PAGES, colourReset) server.set('trust proxy', true); // the client’s IP address is understood as the left-most entry in the X-Forwarded-For header. if (!dev) { let redisClient; - console.info(`development mode is:`, colourGreen, dev, colourReset, `-> connecting to redis session store at`, colourGreen, `${redisHost}:${redisPort}`, colourReset); + console.info(`development mode is:`, colourGreen, dev, colourReset, `-> connecting to redis session store at`, colourGreen, `${redisHost}:${redisPort}`, colourReset); try { redisClient = createClient({ socket: { @@ -68,7 +68,7 @@ app.prepare().then(() => { } }); } catch (error) { - console.info('Error while creating Redis Client, please ensure that Redis is running and the host is specified as an environment variable if this viz app is in a Docker container'); + console.info('Error while creating Redis Client, please ensure that Redis is running and the host is specified as an environment variable if this viz app is in a Docker container'); console.error(error); } redisClient.connect().catch('Error while creating Redis Client, please ensure that Redis is running and the host is specified as an environment variable if this viz app is in a Docker container', console.error); @@ -79,7 +79,7 @@ app.prepare().then(() => { }); } else { store = new MemoryStore(); // use in-memory store for session data in dev mode - console.info(`development mode is:`, dev ? colourYellow : colourRed, dev, colourReset, `-> using in-memory session store (express-session MemoryStore())`); + console.info(`development mode is:`, dev ? colourYellow : colourRed, dev, colourReset, `-> using in-memory session store (express-session MemoryStore())`); } server.use( @@ -106,15 +106,11 @@ app.prepare().then(() => { const roleProtectedPages = process.env.ROLE_PROTECTED_PAGES.split(','); roleProtectedPages.forEach(page => { server.get(page, keycloak.protect(process.env.ROLE)); - console.info('protecting page', page, 'with role', process.env.ROLE); + console.info('protecting page', page, 'with role', process.env.ROLE); }); - // this is a hack because I cannot figure out why process.env.REACT_APP_USE_GEOSERVER_PROXY is not working on the browser const useGeoServerProxy = process.env.REACT_APP_USE_GEOSERVER_PROXY === 'true'; console.log('REACT_APP_USE_GEOSERVER_PROXY is ' + useGeoServerProxy); - server.get('/env/use-geoserver-proxy', (_req, res) => { - res.json({ useGeoServerProxy }); - }) if (useGeoServerProxy) { console.log('GeoServer requests from MapBox will be sent to /geoserver-proxy') @@ -156,6 +152,6 @@ app.prepare().then(() => { // Start listening on the specified port and log server status server.listen(port, (err) => { if (err) throw err; - console.info('Running at', colourGreen, `http://localhost:${port}${colourReset}`,`(on host / inside container). Development mode :${dev ? colourYellow : colourGreen}`, dev, colourReset); + console.info('Running at', colourGreen, `http://localhost:${port}${colourReset}`, `(on host / inside container). Development mode :${dev ? colourYellow : colourGreen}`, dev, colourReset); }); }); \ No newline at end of file diff --git a/web/twa-vis-platform/code/src/hooks/useGeoServerProxy.ts b/web/twa-vis-platform/code/src/hooks/useGeoServerProxy.ts deleted file mode 100644 index 49f071bd0c6..00000000000 --- a/web/twa-vis-platform/code/src/hooks/useGeoServerProxy.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { useEffect, useState } from 'react'; - -// a fudge because process.env does not work on browser -export function useGeoServerProxy() { - const [useProxy, setUseProxy] = useState(false); - - useEffect(() => { - const fetchProxyValue = async () => { - const response = await fetch('/env/use-geoserver-proxy'); - const data = await response.json(); - setUseProxy(data.useGeoServerProxy); - }; - - fetchProxyValue(); - }, []); - - return { useProxy }; -} \ No newline at end of file diff --git a/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx b/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx index 6d01b41eb81..cd83f08b684 100644 --- a/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx +++ b/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx @@ -7,7 +7,6 @@ import mapboxgl, { Map } from 'mapbox-gl'; import React, { useEffect, useRef } from 'react'; import { CameraPosition, ImageryOption } from 'types/settings'; -import { useGeoServerProxy } from 'hooks/useGeoServerProxy'; // Type definition of incoming properties interface MapProperties { @@ -30,9 +29,7 @@ interface MapProperties { * @returns React component for display. */ export default function MapboxMapComponent(props: MapProperties) { - const mapRef = useRef(); - const mapContainerRef = useRef(); - const { useProxy } = useGeoServerProxy() + const mapContainerRef = useRef(); // Run when component loaded useEffect(() => { @@ -44,7 +41,7 @@ export default function MapboxMapComponent(props: MapProperties) { props.setMap(null); // Reset the map ref } }; - }, [useProxy]); + }, []); // Initialise the map object const initialiseMap = async () => { @@ -56,17 +53,17 @@ export default function MapboxMapComponent(props: MapProperties) { "time": "dusk" }; - mapboxgl.accessToken = process.env.MAPBOX_API_KEY; + mapboxgl.accessToken = process.env.MAPBOX_API_KEY; const map: Map = new mapboxgl.Map({ - container: mapContainerRef.current, + container: mapContainerRef.current, style: defaultImagery.url, center: props.defaultPosition.center, zoom: props.defaultPosition.zoom, bearing: props.defaultPosition.bearing, pitch: props.defaultPosition.pitch, transformRequest: (url) => { - if (useProxy) { + if (process.env.REACT_APP_USE_GEOSERVER_PROXY === 'true') { try { const urlObject = new URL(url); const params = new URLSearchParams(urlObject.search); @@ -106,9 +103,9 @@ export default function MapboxMapComponent(props: MapProperties) { }; return ( - <> -
- + <> +
+ ); } From 79214dcc44243c2dd12f5469e3e351d915913272 Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Tue, 26 Nov 2024 18:04:42 +0800 Subject: [PATCH 09/16] 1383-add-authorization-header-to-getmap-requests: updated version --- web/twa-vis-platform/resources/CHANGELOG.md | 4 ++++ web/twa-vis-platform/resources/VERSION | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/web/twa-vis-platform/resources/CHANGELOG.md b/web/twa-vis-platform/resources/CHANGELOG.md index a9ff6c3a68a..679d2277e36 100644 --- a/web/twa-vis-platform/resources/CHANGELOG.md +++ b/web/twa-vis-platform/resources/CHANGELOG.md @@ -3,6 +3,10 @@ [//]: # (Note that version headers need to start with "## " characters to be picked up by some automated scripts) +## 5.12.0 + +- Add ability to include JWT token in header for MapBox source requests. + ## 5.11.0 ## Improvements diff --git a/web/twa-vis-platform/resources/VERSION b/web/twa-vis-platform/resources/VERSION index 57f82f727ce..1a65f3bdfb9 100644 --- a/web/twa-vis-platform/resources/VERSION +++ b/web/twa-vis-platform/resources/VERSION @@ -1 +1 @@ -5.11.0 \ No newline at end of file +5.12.0 \ No newline at end of file From d77b7a94292d22a5e5a7b9da8f97e21684cfd39d Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Tue, 26 Nov 2024 18:11:43 +0800 Subject: [PATCH 10/16] 1383-add-authorization-header-to-getmap-requests: updated version in docker compose --- web/twa-vis-platform/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/twa-vis-platform/docker-compose.yml b/web/twa-vis-platform/docker-compose.yml index ae3d56ee6d2..08865c2291d 100644 --- a/web/twa-vis-platform/docker-compose.yml +++ b/web/twa-vis-platform/docker-compose.yml @@ -4,7 +4,7 @@ services: # Empty visualisation image for deployment. base: - image: ghcr.io/cambridge-cares/twa-vf:5.11-SNAPSHOT + image: ghcr.io/cambridge-cares/twa-vf:5.12.0 container_name: "twa-vf" restart: "no" environment: From bfdfc2b766f7f27b6c9bfdedccba60819b6f48a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ois=C3=ADn?= Date: Tue, 3 Dec 2024 14:41:58 +0000 Subject: [PATCH 11/16] 1383-add-authorization-header-to-getmap-requests: version number in package.json --- web/twa-vis-platform/code/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/twa-vis-platform/code/package.json b/web/twa-vis-platform/code/package.json index 5fd75a04c53..f203c83e3a8 100644 --- a/web/twa-vis-platform/code/package.json +++ b/web/twa-vis-platform/code/package.json @@ -1,6 +1,6 @@ { "name": "twa-visualisation-platform", - "version": "5.11.1", + "version": "5.12.0", "private": true, "type": "module", "eslintConfig": { From 5b5201be414a64052bf5e7b2f3380be281d827de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ois=C3=ADn?= Date: Tue, 3 Dec 2024 14:42:17 +0000 Subject: [PATCH 12/16] 1383-add-authorization-header-to-getmap-requests: changelog header format fixes --- web/twa-vis-platform/resources/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/twa-vis-platform/resources/CHANGELOG.md b/web/twa-vis-platform/resources/CHANGELOG.md index 0a5aaf881d3..3a7c3ac44ca 100644 --- a/web/twa-vis-platform/resources/CHANGELOG.md +++ b/web/twa-vis-platform/resources/CHANGELOG.md @@ -9,7 +9,7 @@ ## 5.11.1 -## Bug Fixes +### Bug Fixes - Fixed links to optional pages behind nginx @@ -22,7 +22,7 @@ - Update several packages, including a breaking version change of mapbox gl-js - Update node to last LTS of v22, with a view to move to v23 when webpack dependencies can be resolved -## Bug Fixes +### Bug Fixes - Fix tooltip on ribbon remaining engaged on dropdown menu - Change default from 3D maps to 2D maps From 4a4dd5284b1f9e72f40f96930f04dd9a876349d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ois=C3=ADn?= Date: Tue, 3 Dec 2024 17:27:52 +0000 Subject: [PATCH 13/16] 1383-add-authorization-header-to-getmap-requests: tidy up logging --- web/twa-vis-platform/code/server.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/web/twa-vis-platform/code/server.js b/web/twa-vis-platform/code/server.js index 217dcc8fba2..86a1afa8c91 100644 --- a/web/twa-vis-platform/code/server.js +++ b/web/twa-vis-platform/code/server.js @@ -110,11 +110,8 @@ app.prepare().then(() => { }); const useGeoServerProxy = process.env.REACT_APP_USE_GEOSERVER_PROXY === 'true'; - console.log('REACT_APP_USE_GEOSERVER_PROXY is ' + useGeoServerProxy); - - if (useGeoServerProxy) { - console.log('GeoServer requests from MapBox will be sent to /geoserver-proxy') - } + console.info('REACT_APP_USE_GEOSERVER_PROXY is ' + useGeoServerProxy); + console.info('GeoServer requests from MapBox will be sent to /geoserver-proxy') if (useGeoServerProxy) { server.get('/geoserver-proxy', async (req, res) => { From 7e3cc36de25d406711ac9018d125baa1119c7a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ois=C3=ADn?= Date: Tue, 3 Dec 2024 17:56:08 +0000 Subject: [PATCH 14/16] 1383-add-authorization-header-to-getmap-requests: consolidate lockfile --- web/twa-vis-platform/code/pnpm-lock.yaml | 368 ++++++++++++----------- 1 file changed, 198 insertions(+), 170 deletions(-) diff --git a/web/twa-vis-platform/code/pnpm-lock.yaml b/web/twa-vis-platform/code/pnpm-lock.yaml index 38dd6293baf..d747be3393f 100644 --- a/web/twa-vis-platform/code/pnpm-lock.yaml +++ b/web/twa-vis-platform/code/pnpm-lock.yaml @@ -22,10 +22,10 @@ importers: version: 6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/x-data-grid': specifier: ^7.22.2 - version: 7.22.3(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 7.23.0(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@reduxjs/toolkit': specifier: ^2.3.0 - version: 2.3.0(react-redux@9.1.2(@types/react@18.3.12)(react@18.3.1)(redux@5.0.1))(react@18.3.1) + version: 2.4.0(react-redux@9.1.2(@types/react@18.3.12)(react@18.3.1)(redux@5.0.1))(react@18.3.1) '@types/markdown-it': specifier: ^14.1.2 version: 14.1.2 @@ -40,16 +40,19 @@ importers: version: 3.16.3 '@typescript-eslint/eslint-plugin': specifier: ^8.14.0 - version: 8.16.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2) + version: 8.17.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2) '@typescript-eslint/parser': specifier: 8.14.0 version: 8.14.0(eslint@8.57.1)(typescript@5.7.2) + axios: + specifier: ^1.7.7 + version: 1.7.8 chart.js: specifier: ^4.4.6 - version: 4.4.6 + version: 4.4.7 chartjs-adapter-moment: specifier: ^1.0.1 - version: 1.0.1(chart.js@4.4.6)(moment@2.30.1) + version: 1.0.1(chart.js@4.4.7)(moment@2.30.1) connect-redis: specifier: ^7.1.1 version: 7.1.1(express-session@1.18.1) @@ -61,7 +64,7 @@ importers: version: 1.18.1 framer-motion: specifier: ^11.11.17 - version: 11.12.0(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 11.13.0(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) github-markdown-css: specifier: ^5.8.0 version: 5.8.1 @@ -70,7 +73,7 @@ importers: version: 4.0.3 keycloak-connect: specifier: ^26.0.5 - version: 26.0.6 + version: 26.0.7 mapbox-gl: specifier: 3.8.0 version: 3.8.0 @@ -657,27 +660,27 @@ packages: '@types/react': optional: true - '@mui/x-data-grid@7.22.3': - resolution: {integrity: sha512-O6kBf6yt/GkOcWjHca5xWN10qBQ/MkITvJmBuIOtX+LH7YtOAriMgD2zkhNbXxHChi7QdEud3bNC3jw5RLRVCA==} + '@mui/x-data-grid@7.23.0': + resolution: {integrity: sha512-nypSz/7j0HPvW7tRPcZAlQADOiRAE4jTIcxwwJUPLtU17EPJOiw1iB29SRYtUThw4f3aXETPAeT4fzgagpuiKg==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 '@mui/material': ^5.15.14 || ^6.0.0 '@mui/system': ^5.15.14 || ^6.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@emotion/react': optional: true '@emotion/styled': optional: true - '@mui/x-internals@7.21.0': - resolution: {integrity: sha512-94YNyZ0BhK5Z+Tkr90RKf47IVCW8R/1MvdUhh6MCQg6sZa74jsX+x+gEZ4kzuCqOsuyTyxikeQ8vVuCIQiP7UQ==} + '@mui/x-internals@7.23.0': + resolution: {integrity: sha512-bPclKpqUiJYIHqmTxSzMVZi6MH51cQsn5U+8jskaTlo3J4QiMeCYJn/gn7YbeR9GOZFp8hetyHjoQoVHKRXCig==} engines: {node: '>=14.0.0'} peerDependencies: - react: ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 '@next/env@14.2.18': resolution: {integrity: sha512-2vWLOUwIPgoqMJKG6dt35fVXVhgM09tw4tK3/Q34GFXDrfiHlG7iS33VA4ggnjWxjiz9KV5xzfsQzJX6vGAekA==} @@ -791,8 +794,8 @@ packages: peerDependencies: '@redis/client': ^1.0.0 - '@reduxjs/toolkit@2.3.0': - resolution: {integrity: sha512-WC7Yd6cNGfHx8zf+iu+Q1UPTfEcXhQ+ATi7CV1hlrSAaQBdlPzg7Ww/wJHNQem7qG9rxmWoFCDCPubSvFObGzA==} + '@reduxjs/toolkit@2.4.0': + resolution: {integrity: sha512-wJZEuSKj14tvNfxiIiJws0tQN77/rDqucBq528ApebMIRHyWpCanJVQRxQ8WWZC19iCDKxDsGlbAir3F1layxA==} peerDependencies: react: ^16.9.0 || ^17.0.0 || ^18 react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 @@ -989,8 +992,8 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.16.0': - resolution: {integrity: sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==} + '@typescript-eslint/eslint-plugin@8.17.0': + resolution: {integrity: sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -1014,12 +1017,12 @@ packages: resolution: {integrity: sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.16.0': - resolution: {integrity: sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==} + '@typescript-eslint/scope-manager@8.17.0': + resolution: {integrity: sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.16.0': - resolution: {integrity: sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==} + '@typescript-eslint/type-utils@8.17.0': + resolution: {integrity: sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -1032,8 +1035,8 @@ packages: resolution: {integrity: sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.16.0': - resolution: {integrity: sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==} + '@typescript-eslint/types@8.17.0': + resolution: {integrity: sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.14.0': @@ -1045,8 +1048,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.16.0': - resolution: {integrity: sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==} + '@typescript-eslint/typescript-estree@8.17.0': + resolution: {integrity: sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -1054,8 +1057,8 @@ packages: typescript: optional: true - '@typescript-eslint/utils@8.16.0': - resolution: {integrity: sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==} + '@typescript-eslint/utils@8.17.0': + resolution: {integrity: sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -1068,8 +1071,8 @@ packages: resolution: {integrity: sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.16.0': - resolution: {integrity: sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==} + '@typescript-eslint/visitor-keys@8.17.0': + resolution: {integrity: sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.2.0': @@ -1315,8 +1318,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001684: - resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==} + caniuse-lite@1.0.30001686: + resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1341,8 +1344,8 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - chart.js@4.4.6: - resolution: {integrity: sha512-8Y406zevUPbbIBA/HRk33khEmQPk5+cxeflWE/2rx1NJsjVWMPw/9mSP9rxHP5eqi6LNoPBVMfZHxbwLSgldYA==} + chart.js@4.4.7: + resolution: {integrity: sha512-pwkcKfdzTMAU/+jNosKhNL2bHtJc/sSmYgVbuGTEDhzkrhmyihmP7vUc/5ZK9WopidMDHNe3Wm7jOd/WhuHWuw==} engines: {pnpm: '>=8'} chartjs-adapter-moment@1.0.1: @@ -1596,8 +1599,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.66: - resolution: {integrity: sha512-pI2QF6+i+zjPbqRzJwkMvtvkdI7MjVbSh2g8dlMguDJIXEPw+kwasS1Jl+YGPEBfGVxsVgGUratAKymPdPo2vQ==} + electron-to-chromium@1.5.68: + resolution: {integrity: sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==} elliptic@6.6.1: resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} @@ -1697,8 +1700,8 @@ packages: eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - eslint-import-resolver-typescript@3.6.3: - resolution: {integrity: sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==} + eslint-import-resolver-typescript@3.7.0: + resolution: {integrity: sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -1927,8 +1930,8 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - framer-motion@11.12.0: - resolution: {integrity: sha512-gZaZeqFM6pX9kMVti60hYAa75jGpSsGYWAHbBfIkuHN7DkVHVkxSxeNYnrGmHuM0zPkWTzQx10ZT+fDjn7N4SA==} + framer-motion@11.13.0: + resolution: {integrity: sha512-Z+hSzTWX5IwhFnopIPi9rse08gYjfjoR2U9AOaCzpKv269M/8jYFF2ITmfi3saHqsox2tbsnsc7PuRqkTllGJw==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 @@ -2052,8 +2055,9 @@ packages: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + gopd@1.1.0: + resolution: {integrity: sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==} + engines: {node: '>= 0.4'} graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2078,12 +2082,12 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + has-proto@1.1.0: + resolution: {integrity: sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==} engines: {node: '>= 0.4'} - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} has-tostringtag@1.0.2: @@ -2201,11 +2205,12 @@ packages: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} - is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} - is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + is-boolean-object@1.2.0: + resolution: {integrity: sha512-kR5g0+dXf/+kXnqI+lu0URKYPKgICtHGGNCDSB10AaUFj3o/HkB3u7WfpRBJGFopxxY0oH3ux7ZsDjLtK7xqvw==} engines: {node: '>= 0.4'} is-bun-module@1.3.0: @@ -2273,8 +2278,8 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + is-number-object@1.1.0: + resolution: {integrity: sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==} engines: {node: '>= 0.4'} is-number@7.0.0: @@ -2293,8 +2298,8 @@ packages: resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} engines: {node: '>=0.10.0'} - is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + is-regex@1.2.0: + resolution: {integrity: sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==} engines: {node: '>= 0.4'} is-set@2.0.3: @@ -2309,12 +2314,12 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + is-string@1.1.0: + resolution: {integrity: sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==} engines: {node: '>= 0.4'} - is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + is-symbol@1.1.0: + resolution: {integrity: sha512-qS8KkNNXUZ/I+nX6QT8ZS1/Yx0A444yhzdTKxCzKkNjQ9sHErBxJnJAgh+f5YhusYECEcjo4XcyH87hn6+ks0A==} engines: {node: '>= 0.4'} is-typed-array@1.1.13: @@ -2571,8 +2576,8 @@ packages: kdbush@4.0.2: resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==} - keycloak-connect@26.0.6: - resolution: {integrity: sha512-Iar65dO8EMxrMzzeGTc2AOjyBRGXKZCqHInqJdRAzuYwkh3IiJZdyZ9pHxA0x+JXkZMKO5jQe98ulenkev612w==} + keycloak-connect@26.0.7: + resolution: {integrity: sha512-m4RbXaiAr3A4zJRvlZtXnpDQyD7Umtm21aL95xSATV7TlaJOpOQdFtCheL5tPT9nTkW6p4VqXsFRvpriqTEuMQ==} engines: {node: '>=14'} keyv@4.5.4: @@ -2817,6 +2822,12 @@ packages: moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + motion-dom@11.13.0: + resolution: {integrity: sha512-Oc1MLGJQ6nrvXccXA89lXtOqFyBmvHtaDcTRGT66o8Czl7nuA8BeHAd9MQV1pQKX0d2RHFBFaw5g3k23hQJt0w==} + + motion-utils@11.13.0: + resolution: {integrity: sha512-lq6TzXkH5c/ysJQBxgLXgM01qwBH1b4goTPh57VvZWJbVJZF/0SB31UWEn4EIqbVPf3au88n2rvK17SpDTja1A==} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -3275,8 +3286,8 @@ packages: resolve-protobuf-schema@2.1.0: resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} - resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} engines: {node: '>=10'} resolve@1.22.8: @@ -3437,6 +3448,9 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + stable-hash@0.0.4: + resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -3582,8 +3596,8 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - ts-api-utils@1.4.2: - resolution: {integrity: sha512-ZF5gQIQa/UmzfvxbHZI3JXN0/Jt+vnAfAviNRAMc491laiK6YCLpCW9ft8oaCRFOTxCZtUTE6XB0ZQAe3olntw==} + ts-api-utils@1.4.3: + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' @@ -3764,8 +3778,9 @@ packages: warning@4.0.3: resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} - which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-boxed-primitive@1.1.0: + resolution: {integrity: sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==} + engines: {node: '>= 0.4'} which-builtin-type@1.2.0: resolution: {integrity: sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==} @@ -4472,13 +4487,13 @@ snapshots: optionalDependencies: '@types/react': 18.3.12 - '@mui/x-data-grid@7.22.3(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/x-data-grid@7.23.0(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.26.0 '@mui/material': 6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/system': 6.1.9(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mui/utils': 6.1.9(@types/react@18.3.12)(react@18.3.1) - '@mui/x-internals': 7.21.0(@types/react@18.3.12)(react@18.3.1) + '@mui/x-internals': 7.23.0(@types/react@18.3.12)(react@18.3.1) clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 @@ -4490,7 +4505,7 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@mui/x-internals@7.21.0(@types/react@18.3.12)(react@18.3.1)': + '@mui/x-internals@7.23.0(@types/react@18.3.12)(react@18.3.1)': dependencies: '@babel/runtime': 7.26.0 '@mui/utils': 6.1.9(@types/react@18.3.12)(react@18.3.1) @@ -4576,7 +4591,7 @@ snapshots: dependencies: '@redis/client': 1.6.0 - '@reduxjs/toolkit@2.3.0(react-redux@9.1.2(@types/react@18.3.12)(react@18.3.1)(redux@5.0.1))(react@18.3.1)': + '@reduxjs/toolkit@2.4.0(react-redux@9.1.2(@types/react@18.3.12)(react@18.3.1)(redux@5.0.1))(react@18.3.1)': dependencies: immer: 10.1.1 redux: 5.0.1 @@ -4804,19 +4819,19 @@ snapshots: '@types/node': 22.10.1 optional: true - '@typescript-eslint/eslint-plugin@8.16.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2)': + '@typescript-eslint/eslint-plugin@8.17.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2)': dependencies: '@eslint-community/regexpp': 4.12.1 '@typescript-eslint/parser': 8.14.0(eslint@8.57.1)(typescript@5.7.2) - '@typescript-eslint/scope-manager': 8.16.0 - '@typescript-eslint/type-utils': 8.16.0(eslint@8.57.1)(typescript@5.7.2) - '@typescript-eslint/utils': 8.16.0(eslint@8.57.1)(typescript@5.7.2) - '@typescript-eslint/visitor-keys': 8.16.0 + '@typescript-eslint/scope-manager': 8.17.0 + '@typescript-eslint/type-utils': 8.17.0(eslint@8.57.1)(typescript@5.7.2) + '@typescript-eslint/utils': 8.17.0(eslint@8.57.1)(typescript@5.7.2) + '@typescript-eslint/visitor-keys': 8.17.0 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.4.2(typescript@5.7.2) + ts-api-utils: 1.4.3(typescript@5.7.2) optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: @@ -4840,18 +4855,18 @@ snapshots: '@typescript-eslint/types': 8.14.0 '@typescript-eslint/visitor-keys': 8.14.0 - '@typescript-eslint/scope-manager@8.16.0': + '@typescript-eslint/scope-manager@8.17.0': dependencies: - '@typescript-eslint/types': 8.16.0 - '@typescript-eslint/visitor-keys': 8.16.0 + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/visitor-keys': 8.17.0 - '@typescript-eslint/type-utils@8.16.0(eslint@8.57.1)(typescript@5.7.2)': + '@typescript-eslint/type-utils@8.17.0(eslint@8.57.1)(typescript@5.7.2)': dependencies: - '@typescript-eslint/typescript-estree': 8.16.0(typescript@5.7.2) - '@typescript-eslint/utils': 8.16.0(eslint@8.57.1)(typescript@5.7.2) + '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) + '@typescript-eslint/utils': 8.17.0(eslint@8.57.1)(typescript@5.7.2) debug: 4.3.7 eslint: 8.57.1 - ts-api-utils: 1.4.2(typescript@5.7.2) + ts-api-utils: 1.4.3(typescript@5.7.2) optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: @@ -4859,7 +4874,7 @@ snapshots: '@typescript-eslint/types@8.14.0': {} - '@typescript-eslint/types@8.16.0': {} + '@typescript-eslint/types@8.17.0': {} '@typescript-eslint/typescript-estree@8.14.0(typescript@5.7.2)': dependencies: @@ -4870,33 +4885,33 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.4.2(typescript@5.7.2) + ts-api-utils: 1.4.3(typescript@5.7.2) optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.16.0(typescript@5.7.2)': + '@typescript-eslint/typescript-estree@8.17.0(typescript@5.7.2)': dependencies: - '@typescript-eslint/types': 8.16.0 - '@typescript-eslint/visitor-keys': 8.16.0 + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/visitor-keys': 8.17.0 debug: 4.3.7 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.4.2(typescript@5.7.2) + ts-api-utils: 1.4.3(typescript@5.7.2) optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.16.0(eslint@8.57.1)(typescript@5.7.2)': + '@typescript-eslint/utils@8.17.0(eslint@8.57.1)(typescript@5.7.2)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.16.0 - '@typescript-eslint/types': 8.16.0 - '@typescript-eslint/typescript-estree': 8.16.0(typescript@5.7.2) + '@typescript-eslint/scope-manager': 8.17.0 + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) eslint: 8.57.1 optionalDependencies: typescript: 5.7.2 @@ -4908,9 +4923,9 @@ snapshots: '@typescript-eslint/types': 8.14.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.16.0': + '@typescript-eslint/visitor-keys@8.17.0': dependencies: - '@typescript-eslint/types': 8.16.0 + '@typescript-eslint/types': 8.17.0 eslint-visitor-keys: 4.2.0 '@ungap/structured-clone@1.2.0': {} @@ -4985,7 +5000,7 @@ snapshots: es-abstract: 1.23.5 es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 - is-string: 1.0.7 + is-string: 1.1.0 array.prototype.findlast@1.2.5: dependencies: @@ -5178,8 +5193,8 @@ snapshots: browserslist@4.24.2: dependencies: - caniuse-lite: 1.0.30001684 - electron-to-chromium: 1.5.66 + caniuse-lite: 1.0.30001686 + electron-to-chromium: 1.5.68 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) @@ -5225,7 +5240,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001684: {} + caniuse-lite@1.0.30001686: {} ccount@2.0.1: {} @@ -5244,13 +5259,13 @@ snapshots: character-reference-invalid@2.0.1: {} - chart.js@4.4.6: + chart.js@4.4.7: dependencies: '@kurkle/color': 0.3.4 - chartjs-adapter-moment@1.0.1(chart.js@4.4.6)(moment@2.30.1): + chartjs-adapter-moment@1.0.1(chart.js@4.4.7)(moment@2.30.1): dependencies: - chart.js: 4.4.6 + chart.js: 4.4.7 moment: 2.30.1 cheap-ruler@4.0.0: {} @@ -5417,7 +5432,7 @@ snapshots: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 - gopd: 1.0.1 + gopd: 1.1.0 define-properties@1.2.1: dependencies: @@ -5471,7 +5486,7 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.5.66: {} + electron-to-chromium@1.5.68: {} elliptic@6.6.1: dependencies: @@ -5527,19 +5542,19 @@ snapshots: get-intrinsic: 1.2.4 get-symbol-description: 1.0.2 globalthis: 1.0.4 - gopd: 1.0.1 + gopd: 1.1.0 has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.1.0 + has-symbols: 1.1.0 hasown: 2.0.2 internal-slot: 1.0.7 is-array-buffer: 3.0.4 is-callable: 1.2.7 is-data-view: 1.0.1 is-negative-zero: 2.0.3 - is-regex: 1.1.4 + is-regex: 1.2.0 is-shared-array-buffer: 1.0.3 - is-string: 1.0.7 + is-string: 1.1.0 is-typed-array: 1.1.13 is-weakref: 1.0.2 object-inspect: 1.13.3 @@ -5574,10 +5589,10 @@ snapshots: function-bind: 1.1.2 get-intrinsic: 1.2.4 globalthis: 1.0.4 - gopd: 1.0.1 + gopd: 1.1.0 has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.1.0 + has-symbols: 1.1.0 internal-slot: 1.0.7 iterator.prototype: 1.1.3 safe-array-concat: 1.1.2 @@ -5600,7 +5615,7 @@ snapshots: dependencies: is-callable: 1.2.7 is-date-object: 1.0.5 - is-symbol: 1.0.4 + is-symbol: 1.1.0 escalade@3.2.0: {} @@ -5623,12 +5638,12 @@ snapshots: dependencies: '@next/eslint-plugin-next': 14.2.18 '@rushstack/eslint-patch': 1.10.4 - '@typescript-eslint/eslint-plugin': 8.16.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2) + '@typescript-eslint/eslint-plugin': 8.17.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2) '@typescript-eslint/parser': 8.14.0(eslint@8.57.1)(typescript@5.7.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.2(eslint@8.57.1) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) @@ -5647,37 +5662,34 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.3.0 is-glob: 4.0.3 + stable-hash: 0.0.4 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-node - - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.14.0(eslint@8.57.1)(typescript@5.7.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -5688,7 +5700,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -6012,8 +6024,10 @@ snapshots: forwarded@0.2.0: {} - framer-motion@11.12.0(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + framer-motion@11.13.0(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: + motion-dom: 11.13.0 + motion-utils: 11.13.0 tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.3.1 @@ -6059,8 +6073,8 @@ snapshots: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.1.0 + has-symbols: 1.1.0 hasown: 2.0.2 get-package-type@0.1.0: {} @@ -6132,9 +6146,9 @@ snapshots: globalthis@1.0.4: dependencies: define-properties: 1.2.1 - gopd: 1.0.1 + gopd: 1.1.0 - gopd@1.0.1: + gopd@1.1.0: dependencies: get-intrinsic: 1.2.4 @@ -6159,13 +6173,15 @@ snapshots: dependencies: es-define-property: 1.0.0 - has-proto@1.0.3: {} + has-proto@1.1.0: + dependencies: + call-bind: 1.0.7 - has-symbols@1.0.3: {} + has-symbols@1.1.0: {} has-tostringtag@1.0.2: dependencies: - has-symbols: 1.0.3 + has-symbols: 1.1.0 hash.js@1.1.7: dependencies: @@ -6306,11 +6322,11 @@ snapshots: dependencies: has-tostringtag: 1.0.2 - is-bigint@1.0.4: + is-bigint@1.1.0: dependencies: has-bigints: 1.0.2 - is-boolean-object@1.1.2: + is-boolean-object@1.2.0: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.2 @@ -6365,8 +6381,9 @@ snapshots: is-negative-zero@2.0.3: {} - is-number-object@1.0.7: + is-number-object@1.1.0: dependencies: + call-bind: 1.0.7 has-tostringtag: 1.0.2 is-number@7.0.0: {} @@ -6379,10 +6396,12 @@ snapshots: dependencies: isobject: 3.0.1 - is-regex@1.1.4: + is-regex@1.2.0: dependencies: call-bind: 1.0.7 + gopd: 1.1.0 has-tostringtag: 1.0.2 + hasown: 2.0.2 is-set@2.0.3: {} @@ -6392,13 +6411,16 @@ snapshots: is-stream@2.0.1: {} - is-string@1.0.7: + is-string@1.1.0: dependencies: + call-bind: 1.0.7 has-tostringtag: 1.0.2 - is-symbol@1.0.4: + is-symbol@1.1.0: dependencies: - has-symbols: 1.0.3 + call-bind: 1.0.7 + has-symbols: 1.1.0 + safe-regex-test: 1.0.3 is-typed-array@1.1.13: dependencies: @@ -6476,7 +6498,7 @@ snapshots: dependencies: define-properties: 1.2.1 get-intrinsic: 1.2.4 - has-symbols: 1.0.3 + has-symbols: 1.1.0 reflect.getprototypeof: 1.0.7 set-function-name: 2.0.2 @@ -6672,7 +6694,7 @@ snapshots: jest-util: 29.7.0 jest-validate: 29.7.0 resolve: 1.22.8 - resolve.exports: 2.0.2 + resolve.exports: 2.0.3 slash: 3.0.0 jest-runner@29.7.0: @@ -6855,7 +6877,7 @@ snapshots: kdbush@4.0.2: {} - keycloak-connect@26.0.6: + keycloak-connect@26.0.7: dependencies: jwk-to-pem: 2.0.7 optionalDependencies: @@ -7243,6 +7265,10 @@ snapshots: moment@2.30.1: {} + motion-dom@11.13.0: {} + + motion-utils@11.13.0: {} + ms@2.0.0: {} ms@2.1.2: @@ -7266,7 +7292,7 @@ snapshots: '@next/env': 14.2.18 '@swc/helpers': 0.5.5 busboy: 1.6.0 - caniuse-lite: 1.0.30001684 + caniuse-lite: 1.0.30001686 graceful-fs: 4.2.11 postcss: 8.4.31 react: 18.3.1 @@ -7306,7 +7332,7 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - has-symbols: 1.0.3 + has-symbols: 1.1.0 object-keys: 1.1.1 object.entries@1.1.8: @@ -7695,7 +7721,7 @@ snapshots: es-abstract: 1.23.5 es-errors: 1.3.0 get-intrinsic: 1.2.4 - gopd: 1.0.1 + gopd: 1.1.0 which-builtin-type: 1.2.0 regenerator-runtime@0.14.1: {} @@ -7742,7 +7768,7 @@ snapshots: dependencies: protocol-buffers-schema: 3.6.0 - resolve.exports@2.0.2: {} + resolve.exports@2.0.3: {} resolve@1.22.8: dependencies: @@ -7772,7 +7798,7 @@ snapshots: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 - has-symbols: 1.0.3 + has-symbols: 1.1.0 isarray: 2.0.5 safe-buffer@5.2.1: {} @@ -7781,7 +7807,7 @@ snapshots: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 - is-regex: 1.1.4 + is-regex: 1.2.0 safer-buffer@2.1.2: {} @@ -7833,7 +7859,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 - gopd: 1.0.1 + gopd: 1.1.0 has-property-descriptors: 1.0.2 set-function-name@2.0.2: @@ -7926,6 +7952,8 @@ snapshots: sprintf-js@1.1.3: optional: true + stable-hash@0.0.4: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -7965,8 +7993,8 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-symbols: 1.0.3 + gopd: 1.1.0 + has-symbols: 1.1.0 internal-slot: 1.0.7 regexp.prototype.flags: 1.5.3 set-function-name: 2.0.2 @@ -8079,7 +8107,7 @@ snapshots: trough@2.2.0: {} - ts-api-utils@1.4.2(typescript@5.7.2): + ts-api-utils@1.4.3(typescript@5.7.2): dependencies: typescript: 5.7.2 @@ -8140,8 +8168,8 @@ snapshots: dependencies: call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 + gopd: 1.1.0 + has-proto: 1.1.0 is-typed-array: 1.1.13 typed-array-byte-offset@1.0.3: @@ -8149,8 +8177,8 @@ snapshots: available-typed-arrays: 1.0.7 call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 + gopd: 1.1.0 + has-proto: 1.1.0 is-typed-array: 1.1.13 reflect.getprototypeof: 1.0.7 @@ -8158,7 +8186,7 @@ snapshots: dependencies: call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 + gopd: 1.1.0 is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 reflect.getprototypeof: 1.0.7 @@ -8181,8 +8209,8 @@ snapshots: dependencies: call-bind: 1.0.7 has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.0 undici-types@6.20.0: {} @@ -8285,13 +8313,13 @@ snapshots: dependencies: loose-envify: 1.4.0 - which-boxed-primitive@1.0.2: + which-boxed-primitive@1.1.0: dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 + is-bigint: 1.1.0 + is-boolean-object: 1.2.0 + is-number-object: 1.1.0 + is-string: 1.1.0 + is-symbol: 1.1.0 which-builtin-type@1.2.0: dependencies: @@ -8302,10 +8330,10 @@ snapshots: is-date-object: 1.0.5 is-finalizationregistry: 1.1.0 is-generator-function: 1.0.10 - is-regex: 1.1.4 + is-regex: 1.2.0 is-weakref: 1.0.2 isarray: 2.0.5 - which-boxed-primitive: 1.0.2 + which-boxed-primitive: 1.1.0 which-collection: 1.0.2 which-typed-array: 1.1.16 @@ -8321,7 +8349,7 @@ snapshots: available-typed-arrays: 1.0.7 call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 + gopd: 1.1.0 has-tostringtag: 1.0.2 which@2.0.2: From 1250573f4f2596ebae7ea3d0953f83696bb369fe Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Wed, 4 Dec 2024 14:56:15 +0800 Subject: [PATCH 15/16] 1383-add-authorization-header-to-getmap-requests: added a new environment variable REACT_APP_SERVER_URL --- web/twa-vis-platform/code/next.config.js | 1 + web/twa-vis-platform/code/server.js | 5 +++-- .../code/src/ui/map/mapbox/mapbox-container.tsx | 5 ++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/web/twa-vis-platform/code/next.config.js b/web/twa-vis-platform/code/next.config.js index c7ad26732c9..1283db6b115 100644 --- a/web/twa-vis-platform/code/next.config.js +++ b/web/twa-vis-platform/code/next.config.js @@ -21,6 +21,7 @@ const nextConfig = { MAPBOX_USER: process.env.MAPBOX_USER, MAPBOX_API_KEY: process.env.MAPBOX_API_KEY, REACT_APP_USE_GEOSERVER_PROXY: process.env.REACT_APP_USE_GEOSERVER_PROXY, + REACT_APP_SERVER_URL: process.env.REACT_APP_SERVER_URL // only used when REACT_APP_USE_GEOSERVER_PROXY is true } }; diff --git a/web/twa-vis-platform/code/server.js b/web/twa-vis-platform/code/server.js index 86a1afa8c91..e3226c63a98 100644 --- a/web/twa-vis-platform/code/server.js +++ b/web/twa-vis-platform/code/server.js @@ -111,10 +111,11 @@ app.prepare().then(() => { const useGeoServerProxy = process.env.REACT_APP_USE_GEOSERVER_PROXY === 'true'; console.info('REACT_APP_USE_GEOSERVER_PROXY is ' + useGeoServerProxy); - console.info('GeoServer requests from MapBox will be sent to /geoserver-proxy') if (useGeoServerProxy) { - server.get('/geoserver-proxy', async (req, res) => { + console.info('Server URL REACT_APP_SERVER_URL is ' + process.env.REACT_APP_SERVER_URL); + console.info('GeoServer requests from MapBox will be sent to ' + process.env.REACT_APP_SERVER_URL + '/geoserver-proxy') + server.get('/geoserver-proxy', keycloak.protect(), async (req, res) => { const targetUrl = req.query.url; let headers = { ...req.headers }; diff --git a/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx b/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx index cd83f08b684..8ee561a2893 100644 --- a/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx +++ b/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx @@ -62,15 +62,14 @@ export default function MapboxMapComponent(props: MapProperties) { zoom: props.defaultPosition.zoom, bearing: props.defaultPosition.bearing, pitch: props.defaultPosition.pitch, - transformRequest: (url) => { + transformRequest: (url: string) => { if (process.env.REACT_APP_USE_GEOSERVER_PROXY === 'true') { try { const urlObject = new URL(url); const params = new URLSearchParams(urlObject.search); if (params.get('request') === 'GetMap') { // not sure if this will work across all conditions - const serverUrl = `${window.location.protocol}//${window.location.host}`; - const proxyUrl = `${serverUrl}/geoserver-proxy?url=${encodeURIComponent(url)}`; + const proxyUrl = `${process.env.REACT_APP_SERVER_URL}/geoserver-proxy?url=${encodeURIComponent(url)}`; return { url: proxyUrl } From f628835082d84b4cb2cb477f75496115c1908237 Mon Sep 17 00:00:00 2001 From: Kok Foong Lee Date: Wed, 4 Dec 2024 15:02:05 +0800 Subject: [PATCH 16/16] 1383-add-authorization-header-to-getmap-requests: added REACT_APP_SERVER_URL to docker compose files --- web/twa-vis-platform/docker-compose.dev.yml | 3 +++ web/twa-vis-platform/docker-compose.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/web/twa-vis-platform/docker-compose.dev.yml b/web/twa-vis-platform/docker-compose.dev.yml index 8312d361b36..0c79812854e 100644 --- a/web/twa-vis-platform/docker-compose.dev.yml +++ b/web/twa-vis-platform/docker-compose.dev.yml @@ -19,6 +19,9 @@ services: ROLE_PROTECTED_PAGES: /add/* ## pages that require a user to have a given REALM or CLIENT role ROLE: protected ## the role required for the above list REACT_APP_USE_GEOSERVER_PROXY: false + REACT_APP_SERVER_URL: http://localhost:3000 # only applicable for REACT_APP_USE_GEOSERVER_PROXY = true + MAPBOX_USERNAME: + MAPBOX_API_KEY: REDIS_HOST: host.docker.internal secrets: diff --git a/web/twa-vis-platform/docker-compose.yml b/web/twa-vis-platform/docker-compose.yml index c5d8da918c9..10428be6a61 100644 --- a/web/twa-vis-platform/docker-compose.yml +++ b/web/twa-vis-platform/docker-compose.yml @@ -13,6 +13,7 @@ services: ROLE_PROTECTED_PAGES: /protected/page/ ## pages that require a user to have a given REALM or CLIENT role ROLE: twa-test:protected ## the role required for the above list REACT_APP_USE_GEOSERVER_PROXY: false + REACT_APP_SERVER_URL: http://localhost:3000 # only applicable for REACT_APP_USE_GEOSERVER_PROXY = true REDIS_HOST: host.docker.internal