diff --git a/adrs/0001-frontend-runtime-env-var-injection.md b/adrs/0001-frontend-runtime-env-var-injection.md new file mode 100644 index 0000000000..2ca8c0409c --- /dev/null +++ b/adrs/0001-frontend-runtime-env-var-injection.md @@ -0,0 +1,67 @@ +# Injection au runtime des variable d'env dans le frontend + +Date: 22/11/2023 + +## Statut + +Résolu + +## Contexte + +Lors du passage de `CRA` à `Vite`, on a perdu la possibilité d'injecter des variables d'environnements au frontend au runtime. + +Pour respecter les 12-factor app et avoir plus d'agilité dans la gestion des variables d'env, nous allons rajouter cette feature. + +Trois options : +1. Utiliser `import-meta-env` qui injecte dans l'`ENTRYPOINT` docker du backend les variables +2. Ajouter un controlleur `Index` dans le backend, qui retourne le contenu de `index.html` lans lequel il injecte des balises `meta` qui contiennent les variables +3. Utiliser le script `env.sh`, qui injecte dans l'`ENTRYPOINT` docker du backend les variables dans le frontend avec le CLI `sed` + +### Utiliser `import-meta-env` + +Cette méthode utilise un fichier `.env.template` qui défini les variables à injecter dynamiquement et gére le développement `compile-time` et la production `runtime`. + +Un fichier `.env.example` permet de filtrer les variables à injecter dans le frontend. + +Il faut rajouter dans l'image docker finale le script `import-meta-env` (préalablement packagé avec `npx pkg`) pour effectuer l'injection dans le fichier `index.html`. + +Cette méthode nécessite de rajouter une nouvelle lib dans notre étape de build. + +### Ajouter un controlleur `Index` dans le backend + +Cette méthode demande: +- D'ajouter les balises `meta` dans le payload retourné sur `/`. (i.e ``) +- De rendre les nom d'assets déterministes (i.e `/assets/index.js`) + - Cela nous oblige à avoir la gestion du cache dans ce controlleur, avec par exemple un `hash=randomString` généré au démarrage +- L'objet JS généré à la volée avec les balises `meta` ne sera pas typé +- Il faut modifier l'env de dev pour avoir + - un build `Vite` "watché" au lieu d'un run de dev watché par défaut + - un `.setCacheControl()` dans le backend pour éviter le caching en dev + +### Utiliser le script `env.sh` + +Ce script utilise un object `env` pour stocker les variables (i.e): +``` +self.env = { + REACT_APP_MONITORENV_URL: '__REACT_APP_MONITORENV_URL__' +} +``` + +Et un script au démarrage de l'image docker avec `ENTRYPOINT ["/home/monitorfish/env.sh"]` (i.e): +``` +sed -i 's#__REACT_APP_MONITORENV_URL__#'"$REACT_APP_MONITORENV_URL"'#g' /home/monitorfish/public/env.js +``` + +- Cette méthode construit un objet `env` non-typé + +## Décision + +Nous rajoutons une injection au runtime des dépendances avec `import-meta-env`. + +Cet outil permet: +1) De ne pas dupliquer la spécification des variables +2) Ne change pas la façon de gérer les env var de `Vite`: `import.meta.env` + +## Conséquences + +Nos devons **obligatoirement** spécifier toutes les variables d'env dans le docker-compose lors du run de l'application `backend` (qui contient le frontend). diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000000..4b627b3ee3 --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1,12 @@ +FRONTEND_GEOSERVER_LOCAL_URL= +FRONTEND_GEOSERVER_REMOTE_URL= +FRONTEND_IS_DEV_ENV= +FRONTEND_MAPBOX_KEY= +FRONTEND_MONITORENV_URL= +FRONTEND_OIDC_AUTHORITY= +FRONTEND_OIDC_CLIENT_ID= +FRONTEND_OIDC_ENABLED= +FRONTEND_OIDC_REDIRECT_URI= +FRONTEND_SENTRY_DSN= +FRONTEND_SHOM_KEY= +VITE_SMALL_CHAT_SNIPPET= diff --git a/frontend/cypress/docker-compose.yml b/frontend/cypress/docker-compose.yml index a43f1bff98..840d6a35f8 100644 --- a/frontend/cypress/docker-compose.yml +++ b/frontend/cypress/docker-compose.yml @@ -34,6 +34,18 @@ services: - SENTRY_DSN= - MONITORENV_URL=http://geoserver-monitorenv-stubs:8080 - MONITORFISH_API_PROTECTED_API_KEY=APIKEY + - FRONTEND_GEOSERVER_LOCAL_URL=http://0.0.0.0:8081 + - FRONTEND_GEOSERVER_REMOTE_URL=http://0.0.0.0:8081 + - FRONTEND_IS_DEV_ENV=true + - FRONTEND_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ + - FRONTEND_MONITORENV_URL=http://0.0.0.0:8081 + - FRONTEND_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish + - FRONTEND_OIDC_CLIENT_ID=monitorfish + - FRONTEND_OIDC_ENABLED=false + - FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr + - FRONTEND_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 + - FRONTEND_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas + - VITE_SMALL_CHAT_SNIPPET= ports: - 8880:8880 - 8000:8000 diff --git a/frontend/cypress/support/e2e.ts b/frontend/cypress/support/e2e.ts index d649ea10da..870955ff8c 100644 --- a/frontend/cypress/support/e2e.ts +++ b/frontend/cypress/support/e2e.ts @@ -114,54 +114,8 @@ beforeEach(() => { statusCode: 200 }) - // DEV :: VITE_GEOSERVER_LOCAL_URL - // PROD :: VITE_GEOSERVER_LOCAL_URL - cy.intercept({ url: /^https?:\/\/10\.56\.205\.25:808(1|2)\/.*/ }, req => { - req.redirect( - req.url - .replace('http://10.56.205.25:8081', 'http://0.0.0.0:8081') - .replace('http://10.56.205.25:8082', 'http://0.0.0.0:8081') - .replace('https://10.56.205.25:8081', 'http://0.0.0.0:8081') - .replace('https://10.56.205.25:8082', 'http://0.0.0.0:8081') - ) - }) - - // DEV :: VITE_GEOSERVER_REMOTE_URL - cy.intercept({ url: /^https?:\/\/monitorfish-test\.csam\.e2\.rie\.gouv\.fr\/.*/ }, req => { - req.redirect( - req.url - .replace('http://monitorfish-test.csam.e2.rie.gouv.fr', 'http://0.0.0.0:8081') - .replace('https://monitorfish-test.csam.e2.rie.gouv.fr', 'http://0.0.0.0:8081') - ) - }) - // PROD :: VITE_GEOSERVER_REMOTE_URL - cy.intercept({ url: /^https?:\/\/monitorfish\.din\.developpement-durable\.gouv\.fr\/.*/ }, req => { - req.redirect( - req.url - .replace('http://monitorfish.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081') - .replace('https://monitorfish.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081') - ) - }) - - // DEV :: VITE_MONITORENV_URL - cy.intercept({ url: /^https?:\/\/monitorenv\.kadata\.fr\/.*/ }, req => { - req.redirect( - req.url - .replace('http://monitorenv.kadata.fr', 'http://0.0.0.0:8081') - .replace('http://monitorenv.kadata.fr', 'https://0.0.0.0:8081') - ) - }) - // PROD :: VITE_MONITORENV_URL - cy.intercept({ url: /^https?:\/\/monitorenv\.din\.developpement-durable\.gouv\.fr\/.*/ }, req => { - req.redirect( - req.url - .replace('http://monitorenv.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081') - .replace('https://monitorenv.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081') - ) - }) - - // DEV :: VITE_SENTRY_DSN - // PROD :: VITE_SENTRY_DSN + // DEV :: FRONTEND_SENTRY_DSN + // PROD :: FRONTEND_SENTRY_DSN cy.intercept( { url: /^https:\/\/a5f3272efa794bb9ada2ffea90f2fec5@sentry\.incubateur\.net\/.*/ }, { @@ -169,7 +123,7 @@ beforeEach(() => { } ) - // PROD :: VITE_SMALL_CHAT_SNIPPET + // PROD :: FRONTEND_SMALL_CHAT_SNIPPET cy.intercept( { url: /^https:\/\/embed\.small\.chat\/.*/ }, { diff --git a/frontend/index.html b/frontend/index.html index 46002f0cf9..ad93b5a08e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -13,7 +13,16 @@
+ + %VITE_SMALL_CHAT_SNIPPET% + + + + + diff --git a/frontend/package-lock.json b/frontend/package-lock.json index bd49ec2a78..7bd5f499d8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -64,6 +64,8 @@ "yup": "^1.3.2" }, "devDependencies": { + "@import-meta-env/cli": "^0.6.8", + "@import-meta-env/unplugin": "^0.5.1", "@jest/globals": "29.6.4", "@swc/core": "1.3.95", "@swc/jest": "0.2.29", @@ -2796,6 +2798,211 @@ "react": "*" } }, + "node_modules/@import-meta-env/cli": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@import-meta-env/cli/-/cli-0.6.8.tgz", + "integrity": "sha512-Lunsmlj02yVtI5drlhNwIUFAQ0wsIUYIrz0Nm5jbvmYvyEUsxC8Qotnf3gXTfvM9Yuutvuc2+dx4uXpa3DajTg==", + "dev": true, + "dependencies": { + "commander": "11.1.0", + "glob": "10.3.10", + "picocolors": "1.0.0", + "serialize-javascript": "6.0.1" + }, + "bin": { + "import-meta-env": "bin/import-meta-env.js" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@import-meta-env/babel": "^0.4.3", + "@import-meta-env/swc": "^0.4.5", + "@import-meta-env/unplugin": "^0.4.8 || ^0.5.0", + "dotenv": "^11.0.0 || ^12.0.4 || ^13.0.1 || ^14.3.2 || ^15.0.1 || ^16.0.0" + }, + "peerDependenciesMeta": { + "@import-meta-env/babel": { + "optional": true + }, + "@import-meta-env/swc": { + "optional": true + }, + "@import-meta-env/unplugin": { + "optional": true + } + } + }, + "node_modules/@import-meta-env/cli/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@import-meta-env/cli/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@import-meta-env/cli/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@import-meta-env/cli/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@import-meta-env/unplugin": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@import-meta-env/unplugin/-/unplugin-0.5.1.tgz", + "integrity": "sha512-2pn+eYha02TY+iJ8WAlGr9SnOx0o+OvddO6lzU9hBxkogWlU9Q1dI/9thacnjL9alOA3R2qGZPd79kaiYtw81A==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "magic-string": "^0.30.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "unplugin": "^1.5.0" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@import-meta-env/cli": "^0.5.1 || ^0.6.0", + "dotenv": "^11.0.0 || ^12.0.4 || ^13.0.1 || ^14.3.2 || ^15.0.1 || ^16.0.0" + }, + "peerDependenciesMeta": { + "@import-meta-env/cli": { + "optional": true + } + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -3863,6 +4070,16 @@ "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.4.tgz", "integrity": "sha512-kB+NJ5Br56ZhElKsf0pM7/PQfrDdDVMRz8f0JM6eVOGE+L89z9hwcst9QvWBBnazzuqGTGtPsJNZoQ1JdNiGSQ==" }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pkgr/utils": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", @@ -6650,6 +6867,15 @@ "node": "*" } }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", @@ -6978,6 +7204,45 @@ "node": ">= 0.8.0" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -10047,6 +10312,34 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -10949,6 +11242,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -11514,6 +11819,24 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -13341,6 +13664,18 @@ "lz-string": "bin/bin.js" } }, + "node_modules/magic-string": { + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -14006,6 +14341,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mkdirp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", @@ -14207,6 +14551,15 @@ "integrity": "sha512-S0sN3agnVh2SZNEIGc0N1X4Z5K0JeFbGBrnuZpsxuUh5XLF0BnvWkMjRXo/zGKLd/eghvNIKcx1pQkmUjXIyrA==", "dev": true }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -14622,6 +14975,31 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.3.tgz", + "integrity": "sha512-B7gr+F6MkqB3uzINHXNctGieGsRTMwIBgxkp0yq/5BwcuDzD4A8wQpHQW6vDAm1uKSLQghmRdD9sKqf2vJ1cEg==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -15103,7 +15481,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -15486,6 +15863,18 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/redux": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", @@ -16077,7 +16466,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "peer": true, "dependencies": { "randombytes": "^2.1.0" } @@ -16496,6 +16884,27 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -16577,6 +16986,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -17572,6 +17994,18 @@ "node": ">= 10.0.0" } }, + "node_modules/unplugin": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.5.1.tgz", + "integrity": "sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew==", + "dev": true, + "dependencies": { + "acorn": "^8.11.2", + "chokidar": "^3.5.3", + "webpack-sources": "^3.2.3", + "webpack-virtual-modules": "^0.6.0" + } + }, "node_modules/untildify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", @@ -18467,11 +18901,16 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "peer": true, "engines": { "node": ">=10.13.0" } }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.0.tgz", + "integrity": "sha512-KnaMTE6EItz/f2q4Gwg5/rmeKVi79OR58NoYnwDJqCk9ywMtTGbBnBcfoBtN4QbYu0lWXvyMoH2Owxuhe4qI6Q==", + "dev": true + }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -18633,6 +19072,24 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 7ef5811a98..992cb380e5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -83,6 +83,8 @@ "yup": "^1.3.2" }, "devDependencies": { + "@import-meta-env/cli": "^0.6.8", + "@import-meta-env/unplugin": "^0.5.1", "@jest/globals": "29.6.4", "@swc/core": "1.3.95", "@swc/jest": "0.2.29", diff --git a/frontend/src/api/geoserver.jsx b/frontend/src/api/geoserver.jsx index 199316497a..341c0c4b17 100644 --- a/frontend/src/api/geoserver.jsx +++ b/frontend/src/api/geoserver.jsx @@ -23,8 +23,8 @@ function getIrretrievableRegulatoryZoneError(e, regulatoryZone) { ) } -export const GEOSERVER_URL = import.meta.env.VITE_GEOSERVER_REMOTE_URL -export const GEOSERVER_BACKOFFICE_URL = import.meta.env.VITE_GEOSERVER_LOCAL_URL +export const GEOSERVER_URL = import.meta.env.FRONTEND_GEOSERVER_REMOTE_URL +export const GEOSERVER_BACKOFFICE_URL = import.meta.env.FRONTEND_GEOSERVER_LOCAL_URL /** * @description This API isn't authenticated diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index 92c43691e0..ef4a9477a4 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -11,7 +11,7 @@ import { normalizeRtkBaseQuery } from '../utils/normalizeRtkBaseQuery' const MAX_RETRIES = 2 // Using local MonitorEnv stubs: -const MONITORENV_API_URL = import.meta.env.VITE_MONITORENV_URL +const MONITORENV_API_URL = import.meta.env.FRONTEND_MONITORENV_URL // Using local MonitorEnv instance: // const MONITORENV_API_URL = 'http://0.0.0.0:9880' diff --git a/frontend/src/auth/getOIDCConfig.ts b/frontend/src/auth/getOIDCConfig.ts index c6c9254ce1..b1744a3f2a 100644 --- a/frontend/src/auth/getOIDCConfig.ts +++ b/frontend/src/auth/getOIDCConfig.ts @@ -5,10 +5,10 @@ import { isCypress } from '../utils/isCypress' const IS_CYPRESS = isCypress() export function getOIDCConfig() { - const IS_OIDC_ENABLED = import.meta.env.VITE_OIDC_ENABLED === 'true' - const OIDC_REDIRECT_URI = import.meta.env.VITE_OIDC_REDIRECT_URI - const OIDC_AUTHORITY = import.meta.env.VITE_OIDC_AUTHORITY - const OIDC_CLIENT_ID = import.meta.env.VITE_OIDC_CLIENT_ID + const IS_OIDC_ENABLED = import.meta.env.FRONTEND_OIDC_ENABLED === 'true' + const OIDC_REDIRECT_URI = import.meta.env.FRONTEND_OIDC_REDIRECT_URI + const OIDC_AUTHORITY = import.meta.env.FRONTEND_OIDC_AUTHORITY + const OIDC_CLIENT_ID = import.meta.env.FRONTEND_OIDC_CLIENT_ID if (IS_OIDC_ENABLED && (!OIDC_REDIRECT_URI || !OIDC_AUTHORITY || !OIDC_CLIENT_ID)) { throw new Error('Cannot setup Cerbère authentication.') diff --git a/frontend/src/auth/getOIDCUser.ts b/frontend/src/auth/getOIDCUser.ts index dd902702cb..2545487dbf 100644 --- a/frontend/src/auth/getOIDCUser.ts +++ b/frontend/src/auth/getOIDCUser.ts @@ -1,8 +1,8 @@ import { User } from 'oidc-client-ts' export function getOIDCUser() { - const OIDC_AUTHORITY = import.meta.env.VITE_OIDC_AUTHORITY - const OIDC_CLIENT_ID = import.meta.env.VITE_OIDC_CLIENT_ID + const OIDC_AUTHORITY = import.meta.env.FRONTEND_OIDC_AUTHORITY + const OIDC_CLIENT_ID = import.meta.env.FRONTEND_OIDC_CLIENT_ID const oidcStorage = localStorage.getItem(`oidc.user:${OIDC_AUTHORITY}:${OIDC_CLIENT_ID}`) if (!oidcStorage) { diff --git a/frontend/src/features/map/layers/BaseLayer.tsx b/frontend/src/features/map/layers/BaseLayer.tsx index 19756a42c7..99392b5c35 100644 --- a/frontend/src/features/map/layers/BaseLayer.tsx +++ b/frontend/src/features/map/layers/BaseLayer.tsx @@ -86,7 +86,7 @@ function UnmemoizedBaseLayer() { source: new XYZ({ maxZoom: 19, url: `https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.jpg90?access_token=${ - import.meta.env.VITE_MAPBOX_KEY + import.meta.env.FRONTEND_MAPBOX_KEY }` }), zIndex: 0 @@ -100,7 +100,7 @@ function UnmemoizedBaseLayer() { // Countries have transparency, so do not fade tiles: transition: 0, - url: `https://services.data.shom.fr/${import.meta.env.VITE_SHOM_KEY}/wms/r` + url: `https://services.data.shom.fr/${import.meta.env.FRONTEND_SHOM_KEY}/wms/r` }), zIndex: 0 }) diff --git a/frontend/src/hooks/authorization/useGetUserAuthorization.ts b/frontend/src/hooks/authorization/useGetUserAuthorization.ts index 443e54f794..d34f9209ca 100644 --- a/frontend/src/hooks/authorization/useGetUserAuthorization.ts +++ b/frontend/src/hooks/authorization/useGetUserAuthorization.ts @@ -9,7 +9,7 @@ import type { UserAuthorization } from '../../domain/entities/authorization/type * Get user authorization */ export function useGetUserAuthorization(): UserAuthorization | undefined { - const IS_OIDC_ENABLED = isCypress() || import.meta.env.VITE_OIDC_ENABLED === 'true' + const IS_OIDC_ENABLED = isCypress() || import.meta.env.FRONTEND_OIDC_ENABLED === 'true' const [userAuthorization, setUserAuthorization] = useState(undefined) useEffect(() => { diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 38f892d7b9..671e49916b 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -19,16 +19,16 @@ import { getOIDCConfig } from './auth/getOIDCConfig' if (import.meta.env.PROD) { // https://docs.sentry.io/platforms/javascript/performance/#configure-the-sample-rate init({ - dsn: import.meta.env.VITE_SENTRY_DSN || '', - environment: import.meta.env.VITE_SENTRY_ENV || '', + dsn: import.meta.env.FRONTEND_SENTRY_DSN || '', + environment: import.meta.env.FRONTEND_SENTRY_ENV || '', integrations: [ new BrowserTracing({ - tracingOrigins: import.meta.env.VITE_SENTRY_TRACING_ORIGINS - ? [import.meta.env.VITE_SENTRY_TRACING_ORIGINS || ''] + tracingOrigins: import.meta.env.FRONTEND_SENTRY_TRACING_ORIGINS + ? [import.meta.env.FRONTEND_SENTRY_TRACING_ORIGINS || ''] : [] }) ], - release: import.meta.env.VITE_MONITORFISH_VERSION || '', + release: import.meta.env.FRONTEND_MONITORFISH_VERSION || '', tracesSampleRate: 1.0 }) } diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 578aa76908..c887f4094e 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -2,6 +2,7 @@ import react from '@vitejs/plugin-react' import { defineConfig } from 'vite' +import importMetaEnv from "@import-meta-env/unplugin" import svgr from 'vite-plugin-svgr' import viteTsconfigPaths from 'vite-tsconfig-paths' @@ -12,7 +13,10 @@ export default defineConfig({ outDir: './build' }, - plugins: [react(), viteTsconfigPaths(), svgr()], + plugins: [react(), viteTsconfigPaths(), svgr(), importMetaEnv.vite({ + env: "../infra/configurations/.env.local", + example: ".env.example" + })], server: { port: 3000, diff --git a/infra/configurations/frontend/.env.dev b/infra/configurations/frontend/.env.dev index 4a9692e14d..5f6233d8c2 100644 --- a/infra/configurations/frontend/.env.dev +++ b/infra/configurations/frontend/.env.dev @@ -1,12 +1,14 @@ -VITE_GEOSERVER_LOCAL_URL=http://10.56.205.25:8081 -VITE_GEOSERVER_REMOTE_URL=http://monitorfish-test.csam.e2.rie.gouv.fr -VITE_IS_DEV_ENV=true -VITE_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ -VITE_MONITORENV_URL=http://monitorenv.kadata.fr -VITE_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish -VITE_OIDC_CLIENT_ID=monitorfish -VITE_OIDC_ENABLED=true -VITE_OIDC_REDIRECT_URI=http://monitorfish-test.csam.e2.rie.gouv.fr -VITE_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 -VITE_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas +FRONTEND_GEOSERVER_LOCAL_URL=http://10.56.205.25:8081 +FRONTEND_GEOSERVER_REMOTE_URL=http://monitorfish-test.csam.e2.rie.gouv.fr +FRONTEND_IS_DEV_ENV=true +FRONTEND_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ +FRONTEND_MONITORENV_URL=http://monitorenv.kadata.fr +FRONTEND_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish +FRONTEND_OIDC_CLIENT_ID=monitorfish +FRONTEND_OIDC_ENABLED=true +FRONTEND_OIDC_REDIRECT_URI=http://monitorfish-test.csam.e2.rie.gouv.fr +FRONTEND_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 +FRONTEND_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas +# We need to use a VITE_ env var to replace the HTML index file +# see: https://vitejs.dev/guide/env-and-mode.html#html-env-replacement VITE_SMALL_CHAT_SNIPPET= diff --git a/infra/configurations/frontend/.env.local b/infra/configurations/frontend/.env.local index bbf2fea2be..8a535e2bec 100644 --- a/infra/configurations/frontend/.env.local +++ b/infra/configurations/frontend/.env.local @@ -1,12 +1,14 @@ -VITE_GEOSERVER_LOCAL_URL=//localhost:8081 -VITE_GEOSERVER_REMOTE_URL=//localhost:8081 -VITE_IS_DEV_ENV=true -VITE_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ -VITE_MONITORENV_URL=//localhost:8081 -VITE_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish -VITE_OIDC_CLIENT_ID=monitorfish -VITE_OIDC_ENABLED=false -VITE_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr -VITE_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 -VITE_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas +FRONTEND_GEOSERVER_LOCAL_URL=//localhost:8081 +FRONTEND_GEOSERVER_REMOTE_URL=//localhost:8081 +FRONTEND_IS_DEV_ENV=true +FRONTEND_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ +FRONTEND_MONITORENV_URL=//localhost:8081 +FRONTEND_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish +FRONTEND_OIDC_CLIENT_ID=monitorfish +FRONTEND_OIDC_ENABLED=false +FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr +FRONTEND_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 +FRONTEND_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas +# We need to use a VITE_ env var to replace the HTML index file +# see: https://vitejs.dev/guide/env-and-mode.html#html-env-replacement VITE_SMALL_CHAT_SNIPPET= diff --git a/infra/configurations/frontend/.env.prod b/infra/configurations/frontend/.env.prod index 612d2d4170..537b702809 100644 --- a/infra/configurations/frontend/.env.prod +++ b/infra/configurations/frontend/.env.prod @@ -1,12 +1,14 @@ -VITE_GEOSERVER_LOCAL_URL=https://10.56.205.25:8082 -VITE_GEOSERVER_REMOTE_URL=https://monitorfish.din.developpement-durable.gouv.fr -VITE_IS_DEV_ENV=false -VITE_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ -VITE_MONITORENV_URL=https://monitorenv.din.developpement-durable.gouv.fr -VITE_OIDC_AUTHORITY=https://authentification.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish -VITE_OIDC_CLIENT_ID=monitorfish -VITE_OIDC_ENABLED=false -VITE_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr -VITE_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 -VITE_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas +FRONTEND_GEOSERVER_LOCAL_URL=https://10.56.205.25:8082 +FRONTEND_GEOSERVER_REMOTE_URL=https://monitorfish.din.developpement-durable.gouv.fr +FRONTEND_IS_DEV_ENV=false +FRONTEND_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ +FRONTEND_MONITORENV_URL=https://monitorenv.din.developpement-durable.gouv.fr +FRONTEND_OIDC_AUTHORITY=https://authentification.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish +FRONTEND_OIDC_CLIENT_ID=monitorfish +FRONTEND_OIDC_ENABLED=false +FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr +FRONTEND_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 +FRONTEND_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas +# We need to use a VITE_ env var to replace the HTML index file +# see: https://vitejs.dev/guide/env-and-mode.html#html-env-replacement VITE_SMALL_CHAT_SNIPPET='' diff --git a/infra/docker/DockerfileBuildApp b/infra/docker/DockerfileBuildApp index d11ed3241c..27690a63d4 100644 --- a/infra/docker/DockerfileBuildApp +++ b/infra/docker/DockerfileBuildApp @@ -46,6 +46,11 @@ WORKDIR /tmp/frontend RUN npm ci RUN npm run build +# Create an `import-meta-env` Alpine executable without node, to be copied to the final image +RUN npx pkg ./node_modules/@import-meta-env/cli/bin/import-meta-env.js \ + --target node16-alpine-x64 \ + --output import-meta-env + ###################### # Upload sourcemaps # ###################### @@ -113,6 +118,12 @@ USER monitorfish RUN mkdir /home/monitorfish/public COPY --from=buildSourcemaps /tmp/frontend/build /home/monitorfish/public/ +# Copy import-meta-env +COPY --from=buildFront /tmp/frontend/import-meta-env /home/monitorfish/ +COPY --from=buildFront /tmp/frontend/.env.example /home/monitorfish/ +COPY --from=buildFront /tmp/infra/docker/env.sh /home/monitorfish/ +COPY --from=buildFront /tmp/infra/configurations/frontend/.env.local /home/monitorfish/ + # Add logs folder to be mounted as volume RUN mkdir /home/monitorfish/logs @@ -125,8 +136,21 @@ ENV SPRING_PROFILES_ACTIVE=$ENV_PROFILE RUN echo ${ENV_PROFILE} +USER root +RUN chown monitorfish /home/monitorfish/import-meta-env +RUN chmod +x /home/monitorfish/import-meta-env + +RUN chown monitorfish /home/monitorfish/env.sh +RUN chmod +x /home/monitorfish/env.sh +RUN chown monitorfish public/index.html +RUN chmod +rwx public/index.html + USER monitorfish ENV VITE_GEOSERVER_LOCAL_URL="" +RUN ./import-meta-env -e .env.local -x .env.example -p public/index.html + +ENTRYPOINT ["/home/monitorfish/env.sh"] + CMD exec java -Dspring.config.additional-location="/home/monitorfish/configurations/" -jar "monitorfish-${VERSION}.jar" diff --git a/infra/docker/env.sh b/infra/docker/env.sh new file mode 100644 index 0000000000..f561f3ea0c --- /dev/null +++ b/infra/docker/env.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e + +./import-meta-env -x .env.example -p public/index.html + +exec "$@" diff --git a/infra/remote/docker-compose.yml b/infra/remote/docker-compose.yml index ced42adf4e..41e7f0b356 100644 --- a/infra/remote/docker-compose.yml +++ b/infra/remote/docker-compose.yml @@ -23,15 +23,19 @@ services: user: "monitorfish:${MONITORFISH_LOGS_AND_BACKUPS_GID}" environment: - ENV_DB_URL=jdbc:postgresql://db:5432/$POSTGRES_DB?user=$POSTGRES_USER&password=$POSTGRES_PASSWORD - - VITE_GEOSERVER_REMOTE_URL=https://monitorfish.din.developpement-durable.gouv.fr - - VITE_GEOSERVER_LOCAL_URL=https://10.56.205.25:8082 - - MONITORFISH_OIDC_SECRET=$MONITORFISH_OIDC_SECRET - - VITE_SENTRY_ENV=${SENTRY_ENV} + - FRONTEND_GEOSERVER_REMOTE_URL=https://monitorfish.din.developpement-durable.gouv.fr + - FRONTEND_GEOSERVER_LOCAL_URL=https://10.56.205.25:8082 + - FRONTEND_SENTRY_ENV=${SENTRY_ENV} - SENTRY_DSN=${SENTRY_DSN} - - VITE_SENTRY_TRACING_ORIGINS=${SENTRY_TRACING_ORIGINS} - - VITE_MONITORFISH_VERSION=${MONITORFISH_VERSION} + - FRONTEND_SENTRY_TRACING_ORIGINS=${SENTRY_TRACING_ORIGINS} + - FRONTEND_MONITORFISH_VERSION=${MONITORFISH_VERSION} - SPRING_PROFILES_ACTIVE=prod - HOST_IP=127.0.0.1 + - FRONTEND_MONITORENV_URL=${MONITORENV_URL} + - MONITORENV_URL=${MONITORENV_URL} + - FRONTEND_OIDC_ENABLED=$MONITORFISH_OIDC_ENABLED + - MONITORFISH_OIDC_ENABLED=$MONITORFISH_OIDC_ENABLED + - MONITORFISH_API_PROTECTED_API_KEY=$MONITORFISH_API_PROTECTED_API_KEY ports: - 8880:8880 - 8000:8000