From b6e95f8285b43e866dd5cdd0fd2e61322b6401b2 Mon Sep 17 00:00:00 2001 From: Jake Low Date: Thu, 10 Oct 2024 21:10:33 -0700 Subject: [PATCH] Inject env vars at runtime instead of build time --- .gitignore | 1 + Dockerfile | 5 ++- docker/90-write-env-to-json.sh | 7 ++++ nginx.conf => docker/nginx.conf | 0 index.html | 10 ++++- package.json | 6 ++- src/App.jsx | 2 +- .../ChallengeCard/ChallengeControls.jsx | 6 +-- .../ChallengeDashboard/ChallengeDashboard.jsx | 4 +- .../EmailRequirementNotice.jsx | 2 +- .../EditChallenge/Schemas/DataSourceSchema.js | 2 +- .../Schemas/InstructionsSchema.js | 2 +- .../EditChallenge/Schemas/ZoomSchema.js | 2 +- .../Manage/ProjectCard/ProjectCard.jsx | 2 +- .../ProjectOverview/ProjectOverview.jsx | 2 +- .../RebuildTasksControl.jsx | 2 +- .../TaskPropertyStyleRules.jsx | 2 +- .../GeographicIndexingNotice.jsx | 2 +- .../ChallengeListWidget.jsx | 2 +- .../ChallengeOverviewWidget.jsx | 2 +- .../Widgets/CommentsWidget/CommentsWidget.jsx | 2 +- .../ChallengeDetail/ChallengeDetail.jsx | 12 +++--- .../ChallengeDetail/FlagCommentInput.jsx | 10 ++--- .../ChallengeResultList.jsx | 4 +- .../StartVirtualChallenge.jsx | 2 +- .../EnhancedMap/LayerToggle/LayerToggle.jsx | 2 +- .../EnhancedMap/PropertyList/PropertyList.jsx | 2 +- src/components/Footer/Footer.jsx | 10 ++--- .../WithChallengeTaskClusters.jsx | 4 +- .../WithCommandInterpreter.jsx | 4 +- .../HOCs/WithTaskReview/WithTaskReview.jsx | 2 +- .../WithUserLocation/WithUserLocation.jsx | 4 +- src/components/HomePane/HomePane.jsx | 4 +- src/components/Navbar/Navbar.jsx | 4 +- .../OSMElementHistory/OSMElementHistory.jsx | 2 +- .../ProjectDetail/ProjectDetail.jsx | 2 +- src/components/SignInButton/SignInButton.jsx | 2 +- src/components/SuperAdmin/MetricsData.jsx | 2 +- .../SuperAdmin/SuperAdminContainer.jsx | 4 +- .../TaskAnalysisTable/TaskAnalysisTable.jsx | 2 +- .../TaskClusterMap/TaskClusterMap.jsx | 4 +- .../ActiveTaskControls/ActiveTaskControls.jsx | 2 +- .../ChallengeShareControls.jsx | 4 +- src/components/TaskPane/TaskPane.jsx | 2 +- .../TaskStatusIndicator.jsx | 2 +- .../MetaReviewStatusMetricsWidget.jsx | 4 +- .../SnapshotProgressWidget.jsx | 2 +- .../TaskMapWidget/RapidEditor/RapidEditor.jsx | 2 +- src/index.jsx | 20 ++++----- src/pages/Leaderboard/Leaderboard.jsx | 4 +- src/pages/Review/Review.jsx | 2 +- src/pages/Social/Social.jsx | 2 +- src/registerServiceWorker.js | 6 +-- src/services/Challenge/Challenge.js | 6 +-- .../ChallengeKeywords/ChallengeKeywords.js | 2 +- src/services/Editor/Editor.js | 12 +++--- .../FundraisingNotices/FundraisingNotices.js | 2 +- src/services/MapBounds/MapBounds.js | 2 +- src/services/Mapillary/Mapillary.js | 2 +- src/services/OSM/OSM.js | 4 +- src/services/OSM/OSM.test.jsx | 4 +- src/services/OSMCha/OSMCha.js | 2 +- src/services/OpenStreetCam/OpenStreetCam.js | 2 +- src/services/Overpass/Overpass.js | 2 +- src/services/Server/Server.js | 4 +- src/services/Server/WebSocketClient.js | 2 +- src/services/Task/TaskClusters.js | 2 +- src/services/Task/TaskReview/TaskReview.js | 10 ++--- src/services/User/Locale/Locale.js | 2 +- src/services/User/User.js | 6 +-- .../VirtualChallenge/VirtualChallenge.js | 2 +- src/services/VisibleLayer/LayerSources.js | 6 +-- src/setupTests.jsx | 12 +++++- src/utils/constructChangesetUrl.js | 10 ++--- src/utils/constructChangesetUrl.test.js | 41 +++++++++++++++++-- vite.config.js | 1 - vitest.config.js | 1 - yarn.lock | 19 ++++++++- 78 files changed, 218 insertions(+), 139 deletions(-) create mode 100755 docker/90-write-env-to-json.sh rename nginx.conf => docker/nginx.conf (100%) diff --git a/.gitignore b/.gitignore index 8a1a111db..dca1b10b6 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ chimp.js .DS_Store .env.local .env.*.local +/public/env.json npm-debug.log* yarn-debug.log* diff --git a/Dockerfile b/Dockerfile index 26b3f8cc3..7301cf38b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,10 @@ RUN yarn run build FROM nginx:1.25-alpine +RUN apk update && apk add jq + COPY --from=builder /maproulette3/dist /srv/www -COPY nginx.conf /etc/nginx/templates/default.conf.template +COPY docker/nginx.conf /etc/nginx/templates/default.conf.template +COPY docker/90-write-env-to-json.sh /docker-entrypoint.d EXPOSE 80 diff --git a/docker/90-write-env-to-json.sh b/docker/90-write-env-to-json.sh new file mode 100755 index 000000000..5f4998c67 --- /dev/null +++ b/docker/90-write-env-to-json.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# Convert env to json and write out to overrides file +jq -n 'env | with_entries(select(.key | startswith("REACT_APP_")))' > /tmp/env.overrides.json +# Merge overrides and defaults together +cp /srv/www/env.json /tmp/env.default.json +jq -s '.[0] * .[1]' /tmp/env.default.json /tmp/env.overrides.json > /srv/www/env.json diff --git a/nginx.conf b/docker/nginx.conf similarity index 100% rename from nginx.conf rename to docker/nginx.conf diff --git a/index.html b/index.html index 51ad93930..f71cf7542 100644 --- a/index.html +++ b/index.html @@ -16,6 +16,9 @@ --> + + + @@ -42,6 +45,11 @@
- + diff --git a/package.json b/package.json index a0700e200..43682efbb 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,7 @@ "@vitejs/plugin-react-swc": "^3.7.1", "@vitest/coverage-v8": "^2.1.2", "dotenv": "^16.4.5", + "dotenv-cli": "^7.4.2", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.7", "eslint": "^8.54.0", @@ -138,9 +139,10 @@ "update-layers": "node scripts/update_layers.js", "update-layers-prod": "NODE_ENV=production node scripts/update_layers.js", "start-js": "vite", - "start": "npm-run-all -p update-layers start-js", + "start": "npm-run-all -p build-env update-layers start-js", + "build-env": "dotenv -c development -- jq -n 'env | with_entries(select(.key | startswith(\"REACT_APP_\")))' > public/env.json", "build-js": "vite build", - "build": "yarn run build-intl && yarn run update-layers-prod && yarn run build-js", + "build": "yarn run build-env && yarn run build-intl && yarn run update-layers-prod && yarn run build-js", "test": "vitest", "test:cov": "vitest run --coverage", "lint": "eslint src/", diff --git a/src/App.jsx b/src/App.jsx index dd13bae3a..80f7c04be 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -92,7 +92,7 @@ export class App extends Component { render() { // We don't currently support mobile devices. Unless the mobile feature // is explicitly enabled, inform user that mobile is not supported. - if (import.meta.env.REACT_APP_FEATURE_MOBILE_DEVICES !== 'enabled') { + if (window.env.REACT_APP_FEATURE_MOBILE_DEVICES !== 'enabled') { // This is a pretty simplistic check, but it should catch most cases. if (/iPhone|iPad|iPod|BlackBerry|IEMobile|Fennec|Android|Mobile|Tablet/i.test(navigator.userAgent)) { return diff --git a/src/components/AdminPane/Manage/ChallengeCard/ChallengeControls.jsx b/src/components/AdminPane/Manage/ChallengeCard/ChallengeControls.jsx index 77bedd1fb..f3636f3c8 100644 --- a/src/components/AdminPane/Manage/ChallengeCard/ChallengeControls.jsx +++ b/src/components/AdminPane/Manage/ChallengeCard/ChallengeControls.jsx @@ -20,7 +20,7 @@ import ConfirmAction from "../../../ConfirmAction/ConfirmAction"; import messages from "../ChallengeDashboard/Messages"; const isEmailRequired = (user) => { - if (import.meta.env.REACT_APP_EMAIL_ENFORCEMENT === "required") { + if (window.env.REACT_APP_EMAIL_ENFORCEMENT === "required") { if (!user?.settings?.email) { return true; } @@ -33,7 +33,7 @@ const handleTasksNeedRebuild = (dateString) => { if (dateString) { const lastRefreshDate = new Date(dateString); const today = new Date(); - const staleMonths = Number(import.meta.env.REACT_APP_ARCHIVE_STALE_TIME_IN_MONTHS) || 6 + const staleMonths = Number(window.env.REACT_APP_ARCHIVE_STALE_TIME_IN_MONTHS) || 6 const staleDate = today.setMonth(today.getMonth() - staleMonths); return lastRefreshDate < staleDate; @@ -136,7 +136,7 @@ export default class ChallengeControls extends Component { )} {this.props.includeCopyURL && (
{" "} - {` ${Number(import.meta.env.REACT_APP_ARCHIVE_STALE_TIME_IN_MONTHS) || 6} `} + {` ${Number(window.env.REACT_APP_ARCHIVE_STALE_TIME_IN_MONTHS) || 6} `}
)} @@ -160,7 +160,7 @@ export class ChallengeDashboard extends Component { challenges={[this.props.challenge]} pageId="ChallengeDashboard" metaReviewEnabled={ - import.meta.env.REACT_APP_FEATURE_META_QC === "enabled" + window.env.REACT_APP_FEATURE_META_QC === "enabled" } /> diff --git a/src/components/AdminPane/Manage/EmailRequirementNotice/EmailRequirementNotice.jsx b/src/components/AdminPane/Manage/EmailRequirementNotice/EmailRequirementNotice.jsx index c2fa402f9..2400d6036 100644 --- a/src/components/AdminPane/Manage/EmailRequirementNotice/EmailRequirementNotice.jsx +++ b/src/components/AdminPane/Manage/EmailRequirementNotice/EmailRequirementNotice.jsx @@ -6,7 +6,7 @@ import SvgSymbol from "../../../SvgSymbol/SvgSymbol"; import messages from "../Messages"; const EmailRequirementNotice = (props) => { - if (import.meta.env.REACT_APP_EMAIL_ENFORCEMENT === "required") { + if (window.env.REACT_APP_EMAIL_ENFORCEMENT === "required") { if (!props.user?.settings?.email) { return (