diff --git a/web/twa-vis-platform/code/next.config.js b/web/twa-vis-platform/code/next.config.js index f5f6e18906..1283db6b11 100644 --- a/web/twa-vis-platform/code/next.config.js +++ b/web/twa-vis-platform/code/next.config.js @@ -1,26 +1,28 @@ /** - 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, + 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/package.json b/web/twa-vis-platform/code/package.json index 3878e8ee38..f203c83e3a 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": { @@ -12,73 +12,74 @@ "engines": { "node": ">=22.0.0" }, - "scripts": { - "dev": "NODE_ENV=development node --env-file='.env.local' server.js", - "dev-docker": "NODE_ENV=development node server.js", + "scripts": { + "dev": "NODE_ENV=development node --env-file='.env.local' server.js", + "dev-docker": "NODE_ENV=development node server.js", "build": "NODE_OPTIONS='--trace-warnings --trace-deprecation' 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": { + "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": { "@emotion/react": "^11.13.5", "@emotion/styled": "^11.13.5", "@mui/icons-material": "^6.1.8", "@mui/material": "^6.1.8", "@mui/x-data-grid": "^7.22.2", - "@reduxjs/toolkit": "^2.3.0", - "@types/markdown-it": "^14.1.2", + "@reduxjs/toolkit": "^2.3.0", + "@types/markdown-it": "^14.1.2", "@types/node": "^22.9.1", - "@types/react": "^18.3.12", - "@types/react-modal": "^3.16.3", + "@types/react": "^18.3.12", + "@types/react-modal": "^3.16.3", "@typescript-eslint/eslint-plugin": "^8.14.0", "@typescript-eslint/parser": "8.14.0", - "chart.js": "^4.4.6", - "chartjs-adapter-moment": "^1.0.1", - "connect-redis": "^7.1.1", - "express": "^4.21.1", - "express-session": "^1.18.1", + "chart.js": "^4.4.6", + "axios": "^1.7.7", + "chartjs-adapter-moment": "^1.0.1", + "connect-redis": "^7.1.1", + "express": "^4.21.1", + "express-session": "^1.18.1", "framer-motion": "^11.11.17", "github-markdown-css": "^5.8.0", - "gray-matter": "^4.0.3", - "keycloak-connect": "^26.0.5", + "gray-matter": "^4.0.3", + "keycloak-connect": "^26.0.5", "mapbox-gl": "3.8.0", - "markdown-it": "^14.1.0", + "markdown-it": "^14.1.0", "material-symbols": "^0.27.0", - "moment": "^2.30.1", + "moment": "^2.30.1", "next": "^14.2.18", - "react": "^18.3.1", - "react-confetti": "^6.1.0", - "react-dom": "^18.3.1", + "react": "^18.3.1", + "react-confetti": "^6.1.0", + "react-dom": "^18.3.1", "react-hook-form": "^7.53.2", "react-inlinesvg": "^4.1.5", - "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-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.28.0", "react-select": "^5.8.3", - "react-toastify": "^10.0.6", - "redis": "^4.7.0", - "redux": "^5.0.1", - "redux-persist": "^6.0.0", - "typescript": "^5.6.3" - }, - "devDependencies": { - "@types/express": "^5.0.0", - "@types/jest": "^29.5.14", - "@types/mapbox": "^1.6.45", - "@types/mapbox-gl": "^3.4.1", - "@types/react-dom": "^18.3.1", - "eslint": "^8.57.1", + "react-toastify": "^10.0.6", + "redis": "^4.7.0", + "redux": "^5.0.1", + "redux-persist": "^6.0.0", + "typescript": "^5.6.3" + }, + "devDependencies": { + "@types/express": "^5.0.0", + "@types/jest": "^29.5.14", + "@types/mapbox": "^1.6.45", + "@types/mapbox-gl": "^3.4.1", + "@types/react-dom": "^18.3.1", + "eslint": "^8.57.1", "eslint-config-next": "^14.2.18", - "eslint-plugin-react": "^7.37.2", - "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" + "eslint-plugin-react": "^7.37.2", + "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 diff --git a/web/twa-vis-platform/code/pnpm-lock.yaml b/web/twa-vis-platform/code/pnpm-lock.yaml index 62d53a8b17..d747be3393 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: @@ -5056,8 +5071,7 @@ snapshots: async@3.2.6: {} - asynckit@0.4.0: - optional: true + asynckit@0.4.0: {} available-typed-arrays@1.0.7: dependencies: @@ -5072,7 +5086,6 @@ snapshots: proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - optional: true axobject-query@4.1.0: {} @@ -5180,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) @@ -5227,7 +5240,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001684: {} + caniuse-lite@1.0.30001686: {} ccount@2.0.1: {} @@ -5246,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: {} @@ -5300,7 +5313,6 @@ snapshots: combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - optional: true comma-separated-tokens@2.0.3: {} @@ -5420,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: @@ -5435,8 +5447,7 @@ snapshots: esprima: 4.0.1 optional: true - delayed-stream@1.0.0: - optional: true + delayed-stream@1.0.0: {} depd@2.0.0: {} @@ -5475,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: @@ -5531,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 @@ -5578,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 @@ -5604,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: {} @@ -5627,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) @@ -5651,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 @@ -5692,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 @@ -5997,8 +6005,7 @@ snapshots: flatted@3.3.2: {} - follow-redirects@1.15.9: - optional: true + follow-redirects@1.15.9: {} for-each@0.3.3: dependencies: @@ -6014,12 +6021,13 @@ snapshots: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - optional: true 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 @@ -6065,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: {} @@ -6138,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 @@ -6165,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: @@ -6312,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 @@ -6371,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: {} @@ -6385,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: {} @@ -6398,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: @@ -6482,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 @@ -6678,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: @@ -6861,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: @@ -7249,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: @@ -7272,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 @@ -7312,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: @@ -7512,8 +7532,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: @@ -7702,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: {} @@ -7749,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: @@ -7779,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: {} @@ -7788,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: {} @@ -7840,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: @@ -7933,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 @@ -7972,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 @@ -8086,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 @@ -8147,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: @@ -8156,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 @@ -8165,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 @@ -8188,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: {} @@ -8292,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: @@ -8309,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 @@ -8328,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: diff --git a/web/twa-vis-platform/code/server.js b/web/twa-vis-platform/code/server.js index 81620429fb..e3226c63a9 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"; @@ -48,75 +49,107 @@ 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.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); - try { - redisClient = createClient({ - socket: { - host: redisHost, - port: redisPort - } + 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) + + 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); + try { + redisClient = createClient({ + socket: { + host: redisHost, + port: redisPort + } + }); + } 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.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.info(`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.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); - store = new RedisStore({ - client: redisClient, - prefix: "redis", - ttl: undefined, - }); - } 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())`); + + 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.info('protecting page', page, 'with role', process.env.ROLE); + }); + + const useGeoServerProxy = process.env.REACT_APP_USE_GEOSERVER_PROXY === 'true'; + console.info('REACT_APP_USE_GEOSERVER_PROXY is ' + useGeoServerProxy); + + if (useGeoServerProxy) { + 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 }; + + 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); + } + }); + } } - 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 }); + // Handle all other requests using Next.js + server.all("*", (req, res) => { + return handle(req, res); }); - 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.info('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.info('Running at', colourGreen, `http://localhost:${port}${colourReset}`, `(on host / inside container). Development mode :${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.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/ui/map/mapbox/mapbox-container.tsx b/web/twa-vis-platform/code/src/ui/map/mapbox/mapbox-container.tsx index fd8c9202f6..8ee561a289 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 @@ -10,11 +10,11 @@ import { CameraPosition, ImageryOption } from 'types/settings'; // Type definition of incoming properties interface MapProperties { - currentMap: Map; - styles: string; - setMap: React.Dispatch>; - defaultPosition: CameraPosition; - imageryOption?: ImageryOption; + currentMap: Map; + styles: string; + setMap: React.Dispatch>; + defaultPosition: CameraPosition; + imageryOption?: ImageryOption; } /** @@ -29,67 +29,83 @@ interface MapProperties { * @returns React component for display. */ export default function MapboxMapComponent(props: MapProperties) { - const mapRef = useRef(); - const mapContainerRef = useRef(); + const mapContainerRef = useRef(); - // 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 + } + }; + }, []); - // Initialise the map object - const initialiseMap = async () => { - props.currentMap?.remove(); + // Initialise the map object + 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" + }; - mapboxgl.accessToken = process.env.MAPBOX_API_KEY; + mapboxgl.accessToken = process.env.MAPBOX_API_KEY; - const map: Map = new mapboxgl.Map({ - container: mapContainerRef.current, - style: defaultImagery.url, - center: props.defaultPosition.center, - zoom: props.defaultPosition.zoom, - bearing: props.defaultPosition.bearing, - pitch: props.defaultPosition.pitch, - }); + const map: Map = new mapboxgl.Map({ + container: mapContainerRef.current, + style: defaultImagery.url, + center: props.defaultPosition.center, + zoom: props.defaultPosition.zoom, + bearing: props.defaultPosition.bearing, + pitch: props.defaultPosition.pitch, + 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 proxyUrl = `${process.env.REACT_APP_SERVER_URL}/geoserver-proxy?url=${encodeURIComponent(url)}`; + 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 - if (defaultImagery.time != null) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (map as any).setConfigProperty( - "basemap", - "lightPreset", - defaultImagery.time - ); - } - // Map is only settable after the styles have loaded - props.setMap(map); - }); - }; + map.on("style.load", function () { + // Update time if using new v3 standard style + if (defaultImagery.time != null) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (map as any).setConfigProperty( + "basemap", + "lightPreset", + defaultImagery.time + ); + } + // Map is only settable after the styles have loaded + props.setMap(map); + }); + }; - return ( - <> -
- - ); + return ( + <> +
+ + ); } MapboxMapComponent.displayName = "MapboxMapComponent"; \ No newline at end of file diff --git a/web/twa-vis-platform/docker-compose.dev.yml b/web/twa-vis-platform/docker-compose.dev.yml index ce6b978e07..0c79812854 100644 --- a/web/twa-vis-platform/docker-compose.dev.yml +++ b/web/twa-vis-platform/docker-compose.dev.yml @@ -18,6 +18,10 @@ 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 + 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 2bc510fe2a..10428be6a6 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.1 + image: ghcr.io/cambridge-cares/twa-vf:5.12.0 container_name: "twa-vf" restart: "no" environment: @@ -12,6 +12,8 @@ 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 + REACT_APP_SERVER_URL: http://localhost:3000 # only applicable for REACT_APP_USE_GEOSERVER_PROXY = true REDIS_HOST: host.docker.internal diff --git a/web/twa-vis-platform/resources/CHANGELOG.md b/web/twa-vis-platform/resources/CHANGELOG.md index 4c3f9504e0..3a7c3ac44c 100644 --- a/web/twa-vis-platform/resources/CHANGELOG.md +++ b/web/twa-vis-platform/resources/CHANGELOG.md @@ -3,9 +3,13 @@ [//]: # (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.1 -## Bug Fixes +### Bug Fixes - Fixed links to optional pages behind nginx @@ -18,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 diff --git a/web/twa-vis-platform/resources/VERSION b/web/twa-vis-platform/resources/VERSION index da7566578a..1a65f3bdfb 100644 --- a/web/twa-vis-platform/resources/VERSION +++ b/web/twa-vis-platform/resources/VERSION @@ -1 +1 @@ -5.11.1 \ No newline at end of file +5.12.0 \ No newline at end of file