feat(settings): set the Google Maps key through PLACES_API_KEY

The server already put PLACES_API_KEY ahead of the key saved in the admin
panel, but nothing said so: the variable was in no template and the admin
field kept showing a stored value that no search used.

GET /me/settings now answers env_keys, the variable behind each key the
environment sets (Google, Unsplash, Amap), and null for that key's value.
The admin field turns read-only and names the variable, Test still probes
the key a search resolves to, and a save leaves those names out so the
stored fallback survives. The variable is documented in .env.example,
docker-compose.yml, the Helm chart (as a secret) and the wiki.

Addresses discussion #1881.
This commit is contained in:
Maurice
2026-09-24 16:17:54 +02:00
parent 79cd3095e0
commit 8906b66bc8
45 changed files with 308 additions and 36 deletions
+1
View File
@@ -157,6 +157,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'مفتاح واجهة برمجة تطبيقات Amap (高德地图)',
'admin.amapKeyHint':
'للبحث عن الأماكن في البر الرئيسي للصين، حيث لا يمكن الوصول إلى Google وتكون بيانات OpenStreetMap شحيحة. يتطلب مفتاحًا من نوع «Web 服务» (خدمة ويب)، وليس مفتاح JS API. يمكن الحصول عليه من console.amap.com.',
'admin.keyFromEnv': 'مُعيَّن عبر {name}',
'admin.placesProvider.title': 'مزوّد البحث عن الأماكن',
'admin.placesProvider.subtitle':
'يجيب فهرس TREK الخاص وOpenStreetMap عن كل بحث. هنا يُختار من يُسأل أيضاً عندما لا يجدان شيئاً: «تلقائي» يفضّل Google عند وجود مفتاح، ثم Amap.',
+1
View File
@@ -135,6 +135,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Chave de API do Amap (高德地图)',
'admin.amapKeyHint':
'Para a busca de lugares na China continental, onde o Google é inacessível e o OpenStreetMap tem poucos dados. Exige uma chave do tipo "Web 服务" (serviço web), não uma chave da API JS. Obtenha em console.amap.com.',
'admin.keyFromEnv': 'Definida via {name}',
'admin.placesProvider.title': 'Provedor de busca de lugares',
'admin.placesProvider.subtitle': 'O índice do próprio TREK e o OpenStreetMap respondem a cada busca. Aqui se escolhe quem mais é consultado quando eles não acham nada: Automático prefere o Google se houver chave, depois Amap.',
'admin.placesProvider.auto': 'Automático',
+1
View File
@@ -446,6 +446,7 @@ const admin: TranslationStrings = {
'admin.amapKey': "Clau API d'Amap (高德地图)",
'admin.amapKeyHint':
"Per a la cerca de llocs a la Xina continental, on Google no és accessible i la cobertura d'OpenStreetMap és escassa. Cal una clau «Web 服务» (servei web), no una clau de l'API JS. Se n'obté una a console.amap.com.",
'admin.keyFromEnv': 'Definida mitjançant {name}',
'admin.placesProvider.title': 'Proveïdor de la cerca de llocs',
'admin.placesProvider.subtitle':
"L'índex propi de TREK i OpenStreetMap responen cada cerca. Aquí es tria a qui més es consulta quan no troben res: Automàtic prefereix Google si hi ha clau, després Amap.",
+1
View File
@@ -135,6 +135,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'API klíč Amap (高德地图)',
'admin.amapKeyHint':
'Pro hledání míst v kontinentální Číně, kde Google není dostupný a OpenStreetMap má málo dat. Vyžaduje klíč typu „Web 服务" (webová služba), nikoli klíč JS API. Získáte na console.amap.com.',
'admin.keyFromEnv': 'Nastaveno přes {name}',
'admin.placesProvider.title': 'Poskytovatel hledání míst',
'admin.placesProvider.subtitle':
'Vlastní index TREKu a OpenStreetMap odpovídají na každé hledání. Zde se volí, koho se zeptat navíc, když nic nenajdou: Automaticky upřednostní Google, pokud je klíč, pak Amap.',
+1
View File
@@ -137,6 +137,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Amap (高德地图) API-Key',
'admin.amapKeyHint':
'Für die Ortssuche in Festlandchina, wo Google nicht erreichbar ist und OpenStreetMap kaum Daten hat. Benötigt einen Key vom Typ „Web 服务" (Webdienst), nicht einen JS-API-Key. Erhältlich auf console.amap.com.',
'admin.keyFromEnv': 'Gesetzt über {name}',
'admin.placesProvider.title': 'Anbieter für die Ortssuche',
'admin.placesProvider.subtitle': 'Der TREK-Index und OpenStreetMap beantworten jede Suche. Hier wird gewählt, wer zusätzlich gefragt wird, wenn die beiden nichts finden: Automatisch bevorzugt Google, wenn ein Schlüssel da ist, danach Amap.',
'admin.placesProvider.auto': 'Automatisch',
+1
View File
@@ -177,6 +177,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Amap (高德地图) API Key',
'admin.amapKeyHint':
'For place search inside mainland China, where Google is unreachable and OpenStreetMap coverage is thin. Needs a "Web 服务" (web service) key, not a JS API key. Get one at console.amap.com.',
'admin.keyFromEnv': 'Set via {name}',
'admin.placesProvider.title': 'Place search provider',
'admin.placesProvider.subtitle': "TREK's own index and OpenStreetMap answer every search. This picks who else is asked when they find nothing: Automatic prefers Google where a key exists, then Amap.",
'admin.placesProvider.auto': 'Automatic',
+1
View File
@@ -137,6 +137,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Clave de API de Amap (高德地图)',
'admin.amapKeyHint':
'Para la búsqueda de lugares en China continental, donde Google no es accesible y OpenStreetMap apenas tiene datos. Requiere una clave de tipo «Web 服务» (servicio web), no una clave de la API de JS. Consíguela en console.amap.com.',
'admin.keyFromEnv': 'Definida mediante {name}',
'admin.placesProvider.title': 'Proveedor de búsqueda de lugares',
'admin.placesProvider.subtitle': 'El índice propio de TREK y OpenStreetMap responden a cada búsqueda. Aquí se elige a quién más se consulta cuando no encuentran nada: Automático prefiere Google si hay clave, luego Amap.',
'admin.placesProvider.auto': 'Automático',
+1
View File
@@ -136,6 +136,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Clé API Amap (高德地图)',
'admin.amapKeyHint':
'Pour la recherche de lieux en Chine continentale, où Google est inaccessible et où OpenStreetMap contient très peu de données. Nécessite une clé de type « Web 服务 » (service web), pas une clé d’API JS. À obtenir sur console.amap.com.',
'admin.keyFromEnv': 'Défini via {name}',
'admin.placesProvider.title': 'Fournisseur de recherche de lieux',
'admin.placesProvider.subtitle': "L'index propre de TREK et OpenStreetMap répondent à chaque recherche. Ceci choisit qui est interrogé en plus quand ils ne trouvent rien : Automatique préfère Google si une clé existe, puis Amap.",
'admin.placesProvider.auto': 'Automatique',
+1
View File
@@ -182,6 +182,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Κλειδί API του Amap (高德地图)',
'admin.amapKeyHint':
'Για αναζήτηση τοποθεσιών στην ηπειρωτική Κίνα, όπου το Google δεν είναι προσβάσιμο και το OpenStreetMap έχει ελάχιστα δεδομένα. Χρειάζεται κλειδί τύπου «Web 服务» (υπηρεσία web), όχι κλειδί JS API. Διαθέσιμο στο console.amap.com.',
'admin.keyFromEnv': 'Ορίζεται μέσω {name}',
'admin.placesProvider.title': 'Πάροχος αναζήτησης τοποθεσιών',
'admin.placesProvider.subtitle':
'Το δικό του ευρετήριο του TREK και το OpenStreetMap απαντούν σε κάθε αναζήτηση. Εδώ επιλέγεται ποιος άλλος ρωτιέται όταν δεν βρίσκουν τίποτα: το Αυτόματο προτιμά τη Google αν υπάρχει κλειδί, μετά το Amap.',
+1
View File
@@ -136,6 +136,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Amap (高德地图) API-kulcs',
'admin.amapKeyHint':
'Helykereséshez Kína szárazföldi részén, ahol a Google nem érhető el, az OpenStreetMap adatai pedig hiányosak. „Web 服务" (webszolgáltatás) típusú kulcs kell hozzá, nem JS API-kulcs. A console.amap.com oldalon kérhető.',
'admin.keyFromEnv': 'Beállítva: {name}',
'admin.placesProvider.title': 'Helykeresési szolgáltató',
'admin.placesProvider.subtitle':
'A TREK saját indexe és az OpenStreetMap minden keresésre válaszol. Itt választod ki, kit kérdezünk még, ha ők nem találnak semmit: az Automatikus a Google-t részesíti előnyben, ha van kulcs, utána az Amapot.',
+1
View File
@@ -178,6 +178,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Kunci API Amap (高德地图)',
'admin.amapKeyHint':
'Untuk pencarian tempat di Tiongkok daratan, tempat Google tidak dapat diakses dan data OpenStreetMap sangat sedikit. Perlu kunci jenis "Web 服务" (layanan web), bukan kunci JS API. Dapatkan di console.amap.com.',
'admin.keyFromEnv': 'Diatur lewat {name}',
'admin.placesProvider.title': 'Penyedia pencarian tempat',
'admin.placesProvider.subtitle':
'Indeks milik TREK dan OpenStreetMap menjawab setiap pencarian. Di sini dipilih siapa lagi yang ditanya bila keduanya tidak menemukan apa pun: Otomatis memilih Google bila ada kunci, lalu Amap.',
+1
View File
@@ -136,6 +136,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Chiave API Amap (高德地图)',
'admin.amapKeyHint':
'Per la ricerca di luoghi nella Cina continentale, dove Google non è raggiungibile e OpenStreetMap ha pochi dati. Serve una chiave di tipo «Web 服务» (servizio web), non una chiave API JS. Si ottiene su console.amap.com.',
'admin.keyFromEnv': 'Impostata tramite {name}',
'admin.placesProvider.title': 'Provider per la ricerca di luoghi',
'admin.placesProvider.subtitle': "L'indice di TREK e OpenStreetMap rispondono a ogni ricerca. Qui si sceglie chi altro viene interrogato quando non trovano nulla: Automatico preferisce Google se esiste una chiave, poi Amap.",
'admin.placesProvider.auto': 'Automatico',
+1
View File
@@ -170,6 +170,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Amap(高德地图)API キー',
'admin.amapKeyHint':
'Google に接続できず OpenStreetMap のデータも少ない中国本土での地点検索用です。JS API キーではなく「Web 服务」(Web サービス)タイプのキーが必要です。console.amap.com で取得できます。',
'admin.keyFromEnv': '{name} で設定済み',
'admin.placesProvider.title': '地点検索のプロバイダー',
'admin.placesProvider.subtitle':
'TREK 自身の索引と OpenStreetMap がすべての検索に答えます。ここでは、それらが何も見つけられなかったときに誰に尋ねるかを選びます。自動はキーがあれば Google を、次に Amap を選びます。',
+1
View File
@@ -175,6 +175,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Amap(高德地图) API 키',
'admin.amapKeyHint':
'Google에 접속할 수 없고 OpenStreetMap 데이터도 부족한 중국 본토에서 장소를 검색할 때 사용합니다. JS API 키가 아니라 "Web 服务"(웹 서비스) 유형의 키가 필요합니다. console.amap.com에서 발급받을 수 있습니다.',
'admin.keyFromEnv': '{name}(으)로 설정됨',
'admin.placesProvider.title': '장소 검색 제공자',
'admin.placesProvider.subtitle':
'TREK 자체 색인과 OpenStreetMap이 모든 검색에 답합니다. 여기서는 둘이 아무것도 찾지 못했을 때 누구에게 더 물을지 고릅니다. 자동은 키가 있으면 Google을, 그다음 Amap을 씁니다.',
+1
View File
@@ -137,6 +137,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Amap (高德地图) API-sleutel',
'admin.amapKeyHint':
'Voor het zoeken naar plaatsen in het Chinese vasteland, waar Google onbereikbaar is en OpenStreetMap weinig gegevens heeft. Vereist een sleutel van het type ‘Web 服务’ (webservice), geen JS API-sleutel. Verkrijgbaar op console.amap.com.',
'admin.keyFromEnv': 'Ingesteld via {name}',
'admin.placesProvider.title': 'Provider voor plaatszoeken',
'admin.placesProvider.subtitle': 'De eigen index van TREK en OpenStreetMap beantwoorden elke zoekopdracht. Hier kies je wie er nog meer wordt gevraagd als zij niets vinden: Automatisch geeft de voorkeur aan Google als er een sleutel is, daarna Amap.',
'admin.placesProvider.auto': 'Automatisch',
+1
View File
@@ -128,6 +128,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Klucz API Amap (高德地图)',
'admin.amapKeyHint':
'Do wyszukiwania miejsc w Chinach kontynentalnych, gdzie Google jest nieosiągalny, a OpenStreetMap ma niewiele danych. Wymaga klucza typu „Web 服务" (usługa sieciowa), a nie klucza JS API. Można go uzyskać na console.amap.com.',
'admin.keyFromEnv': 'Ustawiono przez {name}',
'admin.placesProvider.title': 'Dostawca wyszukiwania miejsc',
'admin.placesProvider.subtitle':
'Własny indeks TREK i OpenStreetMap odpowiadają na każde wyszukiwanie. Tutaj wybierasz, kogo zapytać dodatkowo, gdy nic nie znajdą: Automatycznie preferuje Google, jeśli jest klucz, potem Amap.',
+1
View File
@@ -137,6 +137,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'API-ключ Amap (高德地图)',
'admin.amapKeyHint':
'Для поиска мест в континентальном Китае, где Google недоступен, а данных OpenStreetMap мало. Нужен ключ типа «Web 服务» (веб-сервис), а не ключ JS API. Получить можно на console.amap.com.',
'admin.keyFromEnv': 'Задан через {name}',
'admin.placesProvider.title': 'Провайдер поиска мест',
'admin.placesProvider.subtitle':
'Собственный индекс TREK и OpenStreetMap отвечают на каждый поиск. Здесь выбирается, кого спросить дополнительно, если они ничего не нашли: «Автоматически» предпочитает Google при наличии ключа, затем Amap.',
+1
View File
@@ -179,6 +179,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Amap (高德地图) API-nyckel',
'admin.amapKeyHint':
'För platssökning i Fastlandskina, där Google inte går att nå och OpenStreetMap har tunn täckning. Kräver en "Web 服务"-nyckel (webbtjänst), inte en JS API-nyckel. Skaffa en på console.amap.com.',
'admin.keyFromEnv': 'Satt via {name}',
'admin.placesProvider.title': 'Leverantör för platssökning',
'admin.placesProvider.subtitle':
'TREK:s egen indexering och OpenStreetMap svarar på varje sökning. Här väljs vem som frågas därutöver när de inte hittar något: Automatiskt föredrar Google om en nyckel finns, sedan Amap.',
+1
View File
@@ -179,6 +179,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Amap (高德地图) API Anahtarı',
'admin.amapKeyHint':
'Google’ın erişilemediği ve OpenStreetMap verisinin çok az olduğu Çin anakarasında yer arama için. «Web 服务» (web servisi) türünde bir anahtar gerekir, JS API anahtarı değil. console.amap.com adresinden alınır.',
'admin.keyFromEnv': '{name} ile ayarlandı',
'admin.placesProvider.title': 'Yer arama sağlayıcısı',
'admin.placesProvider.subtitle':
"TREK'in kendi dizini ve OpenStreetMap her aramayı yanıtlar. Burada, onlar bir şey bulamadığında başka kime sorulacağı seçilir: Otomatik, anahtar varsa Google'ı, sonra Amap'i tercih eder.",
+1
View File
@@ -137,6 +137,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'API-ключ Amap (高德地图)',
'admin.amapKeyHint':
'Для пошуку місць у континентальному Китаї, де Google недоступний, а даних OpenStreetMap обмаль. Потрібен ключ типу «Web 服务» (вебсервіс), а не ключ JS API. Отримати можна на console.amap.com.',
'admin.keyFromEnv': 'Задано через {name}',
'admin.placesProvider.title': 'Постачальник пошуку місць',
'admin.placesProvider.subtitle':
'Власний індекс TREK і OpenStreetMap відповідають на кожен пошук. Тут обирається, кого запитати додатково, якщо вони нічого не знайшли: «Автоматично» надає перевагу Google за наявності ключа, потім Amap.',
+1
View File
@@ -178,6 +178,7 @@ const admin: TranslationStrings = {
'admin.amapKey': 'Khóa API Amap (高德地图)',
'admin.amapKeyHint':
'Dùng cho tìm kiếm địa điểm tại Trung Quốc đại lục, nơi không truy cập được Google và dữ liệu OpenStreetMap còn thưa. Cần khóa loại "Web 服务" (dịch vụ web), không phải khóa JS API. Lấy khóa tại console.amap.com.',
'admin.keyFromEnv': 'Đặt qua {name}',
'admin.placesProvider.title': 'Nhà cung cấp tìm kiếm địa điểm',
'admin.placesProvider.subtitle':
'Chỉ mục riêng của TREK và OpenStreetMap trả lời mọi tìm kiếm. Ở đây chọn ai được hỏi thêm khi chúng không tìm thấy gì: Tự động ưu tiên Google nếu có khóa, rồi đến Amap.',
+1
View File
@@ -174,6 +174,7 @@ const admin: TranslationStrings = {
'admin.amapKey': '高德地圖 API Key',
'admin.amapKeyHint':
'用於中國大陸境內的地點搜尋(Google 無法存取,OpenStreetMap 內容也很少)。需要「Web 服務」類型的 Key,而非 JS API Key。在 console.amap.com 申請。',
'admin.keyFromEnv': '已透過 {name} 設定',
'admin.placesProvider.title': '地點搜尋來源',
'admin.placesProvider.subtitle':
'TREK 自有索引和 OpenStreetMap 會回應每一次搜尋。這裡選擇的是它們一無所獲時還問誰:自動在有金鑰時優先 Google,其次 Amap。',
+1
View File
@@ -135,6 +135,7 @@ const admin: TranslationStrings = {
'admin.amapKey': '高德地图 API Key',
'admin.amapKeyHint':
'用于中国大陆境内的地点搜索(Google 无法访问,OpenStreetMap 内容也很少)。需要「Web 服务」类型的 Key,不是 JS API Key。在 console.amap.com 申请。',
'admin.keyFromEnv': '已通过 {name} 设置',
'admin.placesProvider.title': '地点搜索源',
'admin.placesProvider.subtitle':
'TREK 自有索引和 OpenStreetMap 会回应每一次搜索。这里选择的是它们一无所获时还问谁:自动在有密钥时优先 Google,其次 Amap。',