From bc2da2193c90f75300a7590c4acad2bfa827340b Mon Sep 17 00:00:00 2001 From: Angel de la Torre Date: Mon, 6 Oct 2025 12:09:46 -0700 Subject: [PATCH] fix: use two different Google Maps API keys for frontend and backend We got an email from Google about using the same map key for both the frontend and backend applications. Let's split up the keys to apply individual restrictions to them (frontend: website-restricted, backend: IP-restricted). --- .env.base | 6 +++++- .env.template | 6 +++++- app/Helpers/Geocoder.php | 2 +- app/Http/Controllers/API/TimeZoneController.php | 2 +- charts/restarters/templates/_helpers.tpl | 9 +++++++-- charts/restarters/values.yaml | 9 ++++++--- docker-compose.yml | 2 +- resources/views/includes/gmap.blade.php | 2 +- tests/Feature/Users/EditProfileTest.php | 6 +++--- tests/Feature/Users/Registration/AccountCreationTest.php | 6 +++--- 10 files changed, 33 insertions(+), 17 deletions(-) diff --git a/.env.base b/.env.base index 89f7abb909..6908894c5a 100644 --- a/.env.base +++ b/.env.base @@ -161,7 +161,11 @@ SEND_COMMAND_LOGS_TO=tech@yoursite.org # MAPS INTEGRATION # ============================================================================= MAPBOX_TOKEN=1234 -GOOGLE_API_CONSOLE_KEY=1234 +# Google Maps API Keys - SECURITY: Separate restricted keys for different purposes +# Website-restricted key for Maps JavaScript API and Places API (frontend use) +GOOGLE_MAPS_FRONTEND_KEY=1234 +# IP-restricted key for Geocoding API and Time Zone API (backend use) +GOOGLE_MAPS_BACKEND_KEY=1234 # ============================================================================= # MONITORING AND ANALYTICS diff --git a/.env.template b/.env.template index aac9dbc527..795cfea043 100644 --- a/.env.template +++ b/.env.template @@ -161,7 +161,11 @@ SEND_COMMAND_LOGS_TO="$SEND_COMMAND_LOGS_TO" # MAPS INTEGRATION # ============================================================================= MAPBOX_TOKEN="$MAPBOX_TOKEN" -GOOGLE_API_CONSOLE_KEY="$GOOGLE_API_CONSOLE_KEY" +# Google Maps API Keys - SECURITY: Separate restricted keys for different purposes +# Website-restricted key for Maps JavaScript API and Places API (frontend use) +GOOGLE_MAPS_FRONTEND_KEY="$GOOGLE_MAPS_FRONTEND_KEY" +# IP-restricted key for Geocoding API and Time Zone API (backend use) +GOOGLE_MAPS_BACKEND_KEY="$GOOGLE_MAPS_BACKEND_KEY" # ============================================================================= # MONITORING AND ANALYTICS diff --git a/app/Helpers/Geocoder.php b/app/Helpers/Geocoder.php index 6dea4b0f96..41c97305ba 100644 --- a/app/Helpers/Geocoder.php +++ b/app/Helpers/Geocoder.php @@ -11,7 +11,7 @@ public function __construct() private function googleKey() { // We have this so that we can change the key in testing. - return config('GOOGLE_API_CONSOLE_KEY') ?? env('GOOGLE_API_CONSOLE_KEY'); + return config('GOOGLE_MAPS_BACKEND_KEY') ?? env('GOOGLE_MAPS_BACKEND_KEY'); } public function geocode($location) diff --git a/app/Http/Controllers/API/TimeZoneController.php b/app/Http/Controllers/API/TimeZoneController.php index 5d6bfe089b..b81f8ce9ea 100644 --- a/app/Http/Controllers/API/TimeZoneController.php +++ b/app/Http/Controllers/API/TimeZoneController.php @@ -18,7 +18,7 @@ public function lookup(Request $request) return response()->json(['error' => 'Missing lat/lng'], 400); } - $apiKey = env('GOOGLE_API_CONSOLE_KEY'); + $apiKey = env('GOOGLE_MAPS_BACKEND_KEY'); $url = "https://maps.googleapis.com/maps/api/timezone/json?location={$lat},{$lng}×tamp={$timestamp}&key={$apiKey}"; $response = Http::get($url); diff --git a/charts/restarters/templates/_helpers.tpl b/charts/restarters/templates/_helpers.tpl index a252fcb61f..e78fdfd1ce 100644 --- a/charts/restarters/templates/_helpers.tpl +++ b/charts/restarters/templates/_helpers.tpl @@ -60,11 +60,16 @@ Helper to generate environment variables from secrets secretKeyRef: name: {{ .Values.secrets.mapKeys.secretName }} key: {{ .Values.secrets.mapKeys.keys.mapboxToken }} -- name: GOOGLE_API_CONSOLE_KEY +- name: GOOGLE_MAPS_FRONTEND_KEY valueFrom: secretKeyRef: name: {{ .Values.secrets.mapKeys.secretName }} - key: {{ .Values.secrets.mapKeys.keys.googleApiKey }} + key: {{ .Values.secrets.mapKeys.keys.googleMapsFrontendKey }} +- name: GOOGLE_MAPS_BACKEND_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.secrets.mapKeys.secretName }} + key: {{ .Values.secrets.mapKeys.keys.googleMapsBackendKey }} {{- end }} - name: DB_HOST valueFrom: diff --git a/charts/restarters/values.yaml b/charts/restarters/values.yaml index 214e153c6d..19c403229e 100644 --- a/charts/restarters/values.yaml +++ b/charts/restarters/values.yaml @@ -177,10 +177,12 @@ secrets: secretName: "restarters-map-keys" keys: mapboxToken: "MAPBOX_TOKEN" - googleApiKey: "GOOGLE_API_CONSOLE_KEY" + googleMapsFrontendKey: "GOOGLE_MAPS_FRONTEND_KEY" + googleMapsBackendKey: "GOOGLE_MAPS_BACKEND_KEY" data: mapboxToken: "your-mapbox-token-here" - googleApiKey: "your-google-api-key-here" + googleMapsFrontendKey: "your-google-frontend-key-here" + googleMapsBackendKey: "your-google-backend-key-here" # External database credentials # IMPORTANT: For production deployments, create the secret externally and set createSecret: false # For development, you can set createSecret: true and provide values in the data section @@ -341,7 +343,8 @@ envGroups: # Maps integration mapKeys: MAPBOX_TOKEN: "" - GOOGLE_API_CONSOLE_KEY: "" + GOOGLE_MAPS_FRONTEND_KEY: "" + GOOGLE_MAPS_BACKEND_KEY: "" # Monitoring and analytics monitoring: diff --git a/docker-compose.yml b/docker-compose.yml index d6e163bea6..1e798c156d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,7 +22,7 @@ # (or via Docker Desktop's UI on Windows). Check for any obvious errors. # # Then: -# - edit .env and set GOOGLE_API_CONSOLE_KEY to the dev key. +# - edit .env and set GOOGLE_MAPS_FRONTEND_KEY and GOOGLE_MAPS_BACKEND_KEY to the appropriate restricted keys. # # If you want to remove everything to free up disk space or force a complete rebuild (e.g. as a sanity check # after changing this configuration): diff --git a/resources/views/includes/gmap.blade.php b/resources/views/includes/gmap.blade.php index 72ef9ecf9d..40a58350da 100644 --- a/resources/views/includes/gmap.blade.php +++ b/resources/views/includes/gmap.blade.php @@ -1 +1 @@ - + diff --git a/tests/Feature/Users/EditProfileTest.php b/tests/Feature/Users/EditProfileTest.php index 5553cf52e5..c511a08a8c 100644 --- a/tests/Feature/Users/EditProfileTest.php +++ b/tests/Feature/Users/EditProfileTest.php @@ -110,8 +110,8 @@ public function test_location_update(): void $this->assertEquals(51.507, round($user->latitude, 3)); $this->assertEquals(-0.128, round($user->longitude, 3)); - $good = Config::get('GOOGLE_API_CONSOLE_KEY'); - Config::set('GOOGLE_API_CONSOLE_KEY', 'zzz'); + $good = Config::get('GOOGLE_MAPS_BACKEND_KEY'); + Config::set('GOOGLE_MAPS_BACKEND_KEY', 'zzz'); // Supply the id. $this->post('/profile/edit-info', [ @@ -123,7 +123,7 @@ public function test_location_update(): void 'townCity' => 'ZZZZ', ]); - Config::set('GOOGLE_API_CONSOLE_KEY', $good); + Config::set('GOOGLE_MAPS_BACKEND_KEY', $good); $user = $user->fresh(); $this->assertNull($user->latitude); diff --git a/tests/Feature/Users/Registration/AccountCreationTest.php b/tests/Feature/Users/Registration/AccountCreationTest.php index d3ab9929f7..97f3297223 100644 --- a/tests/Feature/Users/Registration/AccountCreationTest.php +++ b/tests/Feature/Users/Registration/AccountCreationTest.php @@ -51,13 +51,13 @@ public function testRegisterInvalidAddress(): void $userAttributes = $this->userAttributes(); // Specify an invalid city and force geocoding to fail by invalidating the Google key. - $good = Config::get('GOOGLE_API_CONSOLE_KEY'); - Config::set('GOOGLE_API_CONSOLE_KEY', 'zzz'); + $good = Config::get('GOOGLE_MAPS_BACKEND_KEY'); + Config::set('GOOGLE_MAPS_BACKEND_KEY', 'zzz'); $userAttributes['city'] = 'zzzzzzz'; $response = $this->post('/user/register/', $userAttributes); - Config::set('GOOGLE_API_CONSOLE_KEY', $good); + Config::set('GOOGLE_MAPS_BACKEND_KEY', $good); $response->assertStatus(302); $response->assertRedirect('dashboard');