From 44e5998c4dbb9d93e0037606c19031f4b447c779 Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 27 Mar 2026 11:08:05 +0100 Subject: [PATCH 1/5] fix: do not proxy on public pages, add proper csp, do not query user config with IUserConfig in public pages, remove unused userId in OsmAPIService, do not save map state in public pages Signed-off-by: Julien Veyssier --- lib/Controller/OsmAPIController.php | 2 +- lib/Listener/CSPListener.php | 6 +++++- lib/Listener/OsmReferenceListener.php | 13 +++++++++++++ lib/Reference/BingReferenceProvider.php | 4 +++- lib/Reference/DuckduckgoReferenceProvider.php | 4 +++- lib/Reference/GoogleMapsReferenceProvider.php | 6 ++++-- lib/Reference/HereMapsReferenceProvider.php | 6 ++++-- lib/Reference/OsmLocationReferenceProvider.php | 6 ++++-- lib/Reference/OsmPointReferenceProvider.php | 9 ++++----- lib/Reference/OsmRouteReferenceProvider.php | 4 +++- lib/Search/OsmSearchLocationProvider.php | 2 +- lib/Service/OsmAPIService.php | 18 +++++++----------- src/components/map/MaplibreMap.vue | 5 +++-- src/lastMapStateHelper.js | 7 +++++++ .../OsmAPIServiceIntegrationTest.php | 6 +++--- 15 files changed, 65 insertions(+), 33 deletions(-) diff --git a/lib/Controller/OsmAPIController.php b/lib/Controller/OsmAPIController.php index 1d63dcf..007c42f 100644 --- a/lib/Controller/OsmAPIController.php +++ b/lib/Controller/OsmAPIController.php @@ -62,7 +62,7 @@ public function nominatimSearch( 'namedetails' => $namedetails, 'extratags' => $extratags, ]; - $searchResults = $this->osmAPIService->searchLocation($this->userId, $q, $rformat, $extraParams, 0, $limit); + $searchResults = $this->osmAPIService->searchLocation($q, $rformat, $extraParams, 0, $limit); if (isset($searchResults['error'])) { return new DataResponse('', Http::STATUS_BAD_REQUEST); } diff --git a/lib/Listener/CSPListener.php b/lib/Listener/CSPListener.php index f468a26..bb8a0c3 100644 --- a/lib/Listener/CSPListener.php +++ b/lib/Listener/CSPListener.php @@ -39,6 +39,7 @@ class CSPListener implements IEventListener { public function __construct( private IRequest $request, private IAppConfig $appConfig, + private ?string $userId, ) { } @@ -56,7 +57,10 @@ public function handle(Event $event): void { ->addAllowedFrameDomain('https://www.openstreetmap.org') ->addAllowedImageDomain('https://*.tile.openstreetmap.org'); - $proxyOsm = $this->appConfig->getValueString(Application::APP_ID, 'proxy_osm', Application::DEFAULT_PROXY_OSM_VALUE) === '1'; + // we do not proxy on public pages + $proxyOsm = $this->userId === null + ? false + : $this->appConfig->getValueString(Application::APP_ID, 'proxy_osm', Application::DEFAULT_PROXY_OSM_VALUE) === '1'; if (!$proxyOsm) { $policy ->addAllowedConnectDomain('https://*.openstreetmap.org') diff --git a/lib/Listener/OsmReferenceListener.php b/lib/Listener/OsmReferenceListener.php index d4c0a14..4795185 100644 --- a/lib/Listener/OsmReferenceListener.php +++ b/lib/Listener/OsmReferenceListener.php @@ -56,6 +56,19 @@ public function handle(Event $event): void { ]; $this->initialState->provideInitialState('api-keys', $userConfig); + // public pages + if ($this->userId === null) { + $this->initialState->provideInitialState('prefer-osm-frame', false); + $this->initialState->provideInitialState('proxy-map-requests', false); + if ($maptilerApiKey === Application::DEFAULT_MAPTILER_API_KEY) { + $this->initialState->provideInitialState('last-map-state', [ + 'mapStyle' => 'osmRaster', + ]); + } + Util::addScript(Application::APP_ID, Application::APP_ID . '-referenceLocation'); + return; + } + $preferSimpleOsmIframe = $this->userConfig->getValueString($this->userId, Application::APP_ID, 'prefer_simple_osm_iframe', '0') === '1'; $this->initialState->provideInitialState('prefer-osm-frame', $preferSimpleOsmIframe); $proxyMapRequests = $this->appConfig->getValueString(Application::APP_ID, 'proxy_osm', Application::DEFAULT_PROXY_OSM_VALUE) === '1'; diff --git a/lib/Reference/BingReferenceProvider.php b/lib/Reference/BingReferenceProvider.php index 81f6bfd..4dec182 100644 --- a/lib/Reference/BingReferenceProvider.php +++ b/lib/Reference/BingReferenceProvider.php @@ -50,7 +50,9 @@ public function __construct( */ public function matchReference(string $referenceText): bool { $adminLinkPreviewEnabled = $this->appConfig->getValueString(Application::APP_ID, 'link_preview_enabled', '1') === '1'; - $userLinkPreviewEnabled = $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; + $userLinkPreviewEnabled = $this->userId === null + ? true + : $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; if (!$adminLinkPreviewEnabled || !$userLinkPreviewEnabled) { return false; } diff --git a/lib/Reference/DuckduckgoReferenceProvider.php b/lib/Reference/DuckduckgoReferenceProvider.php index 4466813..5319486 100644 --- a/lib/Reference/DuckduckgoReferenceProvider.php +++ b/lib/Reference/DuckduckgoReferenceProvider.php @@ -50,7 +50,9 @@ public function __construct( */ public function matchReference(string $referenceText): bool { $adminLinkPreviewEnabled = $this->appConfig->getValueString(Application::APP_ID, 'link_preview_enabled', '1') === '1'; - $userLinkPreviewEnabled = $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; + $userLinkPreviewEnabled = $this->userId === null + ? true + : $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; if (!$adminLinkPreviewEnabled || !$userLinkPreviewEnabled) { return false; } diff --git a/lib/Reference/GoogleMapsReferenceProvider.php b/lib/Reference/GoogleMapsReferenceProvider.php index 063552f..174db90 100644 --- a/lib/Reference/GoogleMapsReferenceProvider.php +++ b/lib/Reference/GoogleMapsReferenceProvider.php @@ -57,7 +57,9 @@ public function __construct( */ public function matchReference(string $referenceText): bool { $adminLinkPreviewEnabled = $this->appConfig->getValueString(Application::APP_ID, 'link_preview_enabled', '1') === '1'; - $userLinkPreviewEnabled = $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; + $userLinkPreviewEnabled = $this->userId === null + ? true + : $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; if (!$adminLinkPreviewEnabled || !$userLinkPreviewEnabled) { return false; } @@ -72,7 +74,7 @@ public function resolveReference(string $referenceText): ?IReference { if ($this->matchReference($referenceText)) { $coords = $this->getCoordinates($referenceText); if ($coords !== null) { - $pointInfo = $this->osmAPIService->geocode($this->userId, $coords['lat'], $coords['lon'], false); + $pointInfo = $this->osmAPIService->geocode($coords['lat'], $coords['lon'], false); if (!isset($pointInfo['error'])) { $pointInfo['url'] = $referenceText; $reference = new Reference($referenceText); diff --git a/lib/Reference/HereMapsReferenceProvider.php b/lib/Reference/HereMapsReferenceProvider.php index dba382c..7672906 100644 --- a/lib/Reference/HereMapsReferenceProvider.php +++ b/lib/Reference/HereMapsReferenceProvider.php @@ -55,7 +55,9 @@ public function __construct( */ public function matchReference(string $referenceText): bool { $adminLinkPreviewEnabled = $this->appConfig->getValueString(Application::APP_ID, 'link_preview_enabled', '1') === '1'; - $userLinkPreviewEnabled = $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; + $userLinkPreviewEnabled = $this->userId === null + ? true + : $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; if (!$adminLinkPreviewEnabled || !$userLinkPreviewEnabled) { return false; } @@ -70,7 +72,7 @@ public function resolveReference(string $referenceText): ?IReference { if ($this->matchReference($referenceText)) { $coords = $this->getCoordinates($referenceText); if ($coords !== null) { - $pointInfo = $this->osmAPIService->geocode($this->userId, $coords['lat'], $coords['lon'], false); + $pointInfo = $this->osmAPIService->geocode($coords['lat'], $coords['lon'], false); if (!isset($pointInfo['error'])) { $pointInfo['url'] = $referenceText; $reference = new Reference($referenceText); diff --git a/lib/Reference/OsmLocationReferenceProvider.php b/lib/Reference/OsmLocationReferenceProvider.php index 56e5a2c..8a4904b 100644 --- a/lib/Reference/OsmLocationReferenceProvider.php +++ b/lib/Reference/OsmLocationReferenceProvider.php @@ -57,7 +57,9 @@ public function __construct( */ public function matchReference(string $referenceText): bool { $adminLinkPreviewEnabled = $this->appConfig->getValueString(Application::APP_ID, 'link_preview_enabled', '1') === '1'; - $userLinkPreviewEnabled = $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; + $userLinkPreviewEnabled = $this->userId === null + ? true + : $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; if (!$adminLinkPreviewEnabled || !$userLinkPreviewEnabled) { return false; } @@ -72,7 +74,7 @@ public function resolveReference(string $referenceText): ?IReference { if ($this->matchReference($referenceText)) { $coords = $this->getCoordinates($referenceText); $locationTypeId = $this->getLocationTypeId($referenceText); - $locationInfo = $this->osmAPIService->getLocationInfo($this->userId, $locationTypeId['id'], $locationTypeId['type']); + $locationInfo = $this->osmAPIService->getLocationInfo($locationTypeId['id'], $locationTypeId['type']); if ($locationInfo !== null) { $locationInfo['url'] = $referenceText; $reference = new Reference($referenceText); diff --git a/lib/Reference/OsmPointReferenceProvider.php b/lib/Reference/OsmPointReferenceProvider.php index 2721f93..bbadbe3 100644 --- a/lib/Reference/OsmPointReferenceProvider.php +++ b/lib/Reference/OsmPointReferenceProvider.php @@ -97,7 +97,9 @@ public function getSupportedSearchProviderIds(): array { */ public function matchReference(string $referenceText): bool { $adminLinkPreviewEnabled = $this->appConfig->getValueString(Application::APP_ID, 'link_preview_enabled', '1') === '1'; - $userLinkPreviewEnabled = $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; + $userLinkPreviewEnabled = $this->userId === null + ? true + : $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; if (!$adminLinkPreviewEnabled || !$userLinkPreviewEnabled) { return false; } @@ -112,10 +114,9 @@ public function resolveReference(string $referenceText): ?IReference { if ($this->matchReference($referenceText)) { $coords = $this->getCoordinates($referenceText); if (isset($coords['markerLat'], $coords['markerLon'])) { - $pointInfo = $this->osmAPIService->geocode($this->userId, $coords['markerLat'], $coords['markerLon']); + $pointInfo = $this->osmAPIService->geocode($coords['markerLat'], $coords['markerLon']); } else { // do not geocode if no marker, the widget will simply show the map centered correctly - // $pointInfo = $this->osmAPIService->geocode($this->userId, $coords['lat'], $coords['lon']); $pointInfo = []; } if (!isset($pointInfo['error'])) { @@ -283,8 +284,6 @@ public static function getFragmentInfo(string $url, array $urlInfo): array { } /** - * We use the userId here because when connecting/disconnecting from the GitHub account, - * we want to invalidate all the user cache and this is only possible with the cache prefix * @inheritDoc */ public function getCachePrefix(string $referenceId): string { diff --git a/lib/Reference/OsmRouteReferenceProvider.php b/lib/Reference/OsmRouteReferenceProvider.php index 4c2cc79..2ad38e1 100644 --- a/lib/Reference/OsmRouteReferenceProvider.php +++ b/lib/Reference/OsmRouteReferenceProvider.php @@ -87,7 +87,9 @@ public function getIconUrl(): string { */ public function matchReference(string $referenceText): bool { $adminLinkPreviewEnabled = $this->appConfig->getValueString(Application::APP_ID, 'link_preview_enabled', '1') === '1'; - $userLinkPreviewEnabled = $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; + $userLinkPreviewEnabled = $this->userId === null + ? true + : $this->userConfig->getValueString($this->userId, Application::APP_ID, 'link_preview_enabled', '1') === '1'; if (!$adminLinkPreviewEnabled || !$userLinkPreviewEnabled) { return false; } diff --git a/lib/Search/OsmSearchLocationProvider.php b/lib/Search/OsmSearchLocationProvider.php index 1ce1f46..1b93b4f 100644 --- a/lib/Search/OsmSearchLocationProvider.php +++ b/lib/Search/OsmSearchLocationProvider.php @@ -105,7 +105,7 @@ public function search(IUser $user, ISearchQuery $query): SearchResult { 'extratags' => 1, 'namedetails' => 1, ]; - $searchResult = $this->osmAPIService->searchLocation($user->getUID(), $term, 'json', $extraParams, $offset, $limit); + $searchResult = $this->osmAPIService->searchLocation($term, 'json', $extraParams, $offset, $limit); if (isset($searchResult['error'])) { $items = []; } else { diff --git a/lib/Service/OsmAPIService.php b/lib/Service/OsmAPIService.php index 951139f..d6f9a78 100644 --- a/lib/Service/OsmAPIService.php +++ b/lib/Service/OsmAPIService.php @@ -113,12 +113,11 @@ public function getLinkFromOsmId(int $osmId, string $osmType): string { * Example location ID: 87515 * Example location type: relation * - * @param string $userId * @param int $locationId * @param string $locationType * @return array|null */ - public function getLocationInfo(string $userId, int $locationId, string $locationType): ?array { + public function getLocationInfo(int $locationId, string $locationType): ?array { // example: // curl https://nominatim.openstreetmap.org/lookup?osm_ids=R87515&format=json&addressdetails=1&extratags=1&namedetails=1&polygon_geojson=1 $prefix = $locationType === 'relation' @@ -134,7 +133,7 @@ public function getLocationInfo(string $userId, int $locationId, string $locatio 'namedetails' => 1, 'polygon_geojson' => 1, ]; - $result = $this->request($userId, 'lookup', $params); + $result = $this->request('lookup', $params); if (count($result) === 1) { return $result[0]; } @@ -146,7 +145,6 @@ public function getLocationInfo(string $userId, int $locationId, string $locatio * Search items * Example query string: "montcuq" * - * @param string $userId * @param string $query * @param string $format * @param array $extraParams @@ -154,7 +152,7 @@ public function getLocationInfo(string $userId, int $locationId, string $locatio * @param int $limit * @return array request result */ - public function searchLocation(string $userId, string $query, string $format, array $extraParams = [], + public function searchLocation(string $query, string $format, array $extraParams = [], int $offset = 0, int $limit = 5): array { // no pagination... $limitParam = $offset + $limit; @@ -168,7 +166,7 @@ public function searchLocation(string $userId, string $query, string $format, ar $params[$k] = $v; } } - $result = $this->request($userId, 'search', $params); + $result = $this->request('search', $params); if (!isset($result['error'])) { return array_slice($result, $offset, $limit); } @@ -181,13 +179,12 @@ public function searchLocation(string $userId, string $query, string $format, ar * lat: 44.3383486 * lon: 1.2086886 * - * @param string $userId * @param float $lat * @param float $lon * @param bool $includePolygon * @return array */ - public function geocode(string $userId, float $lat, float $lon, bool $includePolygon = true): array { + public function geocode(float $lat, float $lon, bool $includePolygon = true): array { // example: // curl https://nominatim.openstreetmap.org/reverse?format=json&lat=44.3383486&lon=1.2086886&addressdetails=1&polygon_geojson=1 $params = [ @@ -199,20 +196,19 @@ public function geocode(string $userId, float $lat, float $lon, bool $includePol if ($includePolygon) { $params['polygon_geojson'] = 1; } - return $this->request($userId, 'reverse', $params); + return $this->request('reverse', $params); } /** * Make an HTTP request to the Osm API * - * @param string|null $userId * @param string $endPoint The path to reach in nominatim * @param array $params Query parameters (key/val pairs) * @param string $method HTTP query method * @param bool $rawResponse * @return array decoded request result or error */ - public function request(?string $userId, string $endPoint, array $params = [], string $method = 'GET', bool $rawResponse = false): array { + public function request(string $endPoint, array $params = [], string $method = 'GET', bool $rawResponse = false): array { try { $url = 'https://nominatim.openstreetmap.org/' . $endPoint; $options = [ diff --git a/src/components/map/MaplibreMap.vue b/src/components/map/MaplibreMap.vue index b13ca86..a7630cf 100644 --- a/src/components/map/MaplibreMap.vue +++ b/src/components/map/MaplibreMap.vue @@ -122,8 +122,9 @@ export default { globeControl: null, myUseGlobe: this.useGlobe, apiKeys: loadState('integration_openstreetmap', 'api-keys'), - // https://api.maptiler.com/resources/logo.svg - maptilerLogoUrl: generateUrl('/apps/integration_openstreetmap/maptiler/resources/logo.svg'), + maptilerLogoUrl: loadState('integration_openstreetmap', 'proxy-map-requests', false) + ? generateUrl('/apps/integration_openstreetmap/maptiler/resources/logo.svg') + : 'https://api.maptiler.com/resources/logo.svg', } }, diff --git a/src/lastMapStateHelper.js b/src/lastMapStateHelper.js index ce60515..8957c48 100644 --- a/src/lastMapStateHelper.js +++ b/src/lastMapStateHelper.js @@ -1,5 +1,6 @@ import { loadState } from '@nextcloud/initial-state' import { generateUrl } from '@nextcloud/router' +import { getCurrentUser } from '@nextcloud/auth' import axios from '@nextcloud/axios' import { linkTypes, routingLinkTypes } from './mapUtils.js' @@ -24,6 +25,12 @@ export function getLastMapState() { } export function setLastMapState({ lat, lon, zoom, pitch, bearing, mapStyle, terrain, globe, linkType, routingLinkType }) { + // in public pages + const currentUser = getCurrentUser() + if (currentUser === null) { + return + } + const state = { lat, lon, zoom, pitch, bearing, mapStyle, terrain, globe, linkType, routingLinkType } Object.keys(state).forEach(k => { if (state[k] !== undefined) { diff --git a/tests/integration/OsmAPIServiceIntegrationTest.php b/tests/integration/OsmAPIServiceIntegrationTest.php index 6d07188..18d6551 100644 --- a/tests/integration/OsmAPIServiceIntegrationTest.php +++ b/tests/integration/OsmAPIServiceIntegrationTest.php @@ -24,7 +24,7 @@ protected function setUp(): void { * that the response can be consumed by reference providers without crashing. */ public function testGeocode(): void { - $result = $this->service->geocode('integration-test', 44.3383486, 1.2086886, false); + $result = $this->service->geocode(44.3383486, 1.2086886, false); $this->assertIsArray($result); $this->assertArrayNotHasKey('error', $result, json_encode($result)); @@ -53,7 +53,7 @@ public function testGeocode(): void { * checks that entries contain the fields used by OsmSearchLocationProvider. */ public function testSearchLocation(): void { - $result = $this->service->searchLocation('integration-test', 'montcuq', 'json', [ + $result = $this->service->searchLocation('montcuq', 'json', [ 'addressdetails' => 1, 'extratags' => 1, 'namedetails' => 1, @@ -86,7 +86,7 @@ public function testSearchLocation(): void { * checks that the returned data can be used by OsmLocationReferenceProvider. */ public function testGetLocationInfo(): void { - $result = $this->service->getLocationInfo('integration-test', 87515, 'relation'); + $result = $this->service->getLocationInfo(87515, 'relation'); $this->assertNotNull($result); $this->assertArrayNotHasKey('error', $result, json_encode($result)); From d8da697a32e07999dae7b215484bd69261590b7b Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 27 Mar 2026 12:24:07 +0100 Subject: [PATCH 2/5] make all reference providers implement IPublicReferenceProvider Signed-off-by: Julien Veyssier --- lib/Reference/BingReferenceProvider.php | 14 +++++++++++++- lib/Reference/DuckduckgoReferenceProvider.php | 14 +++++++++++++- lib/Reference/GoogleMapsReferenceProvider.php | 14 +++++++++++++- lib/Reference/HereMapsReferenceProvider.php | 14 +++++++++++++- lib/Reference/OsmLocationReferenceProvider.php | 14 +++++++++++++- lib/Reference/OsmPointReferenceProvider.php | 14 +++++++++++++- lib/Reference/OsmRouteReferenceProvider.php | 14 +++++++++++++- 7 files changed, 91 insertions(+), 7 deletions(-) diff --git a/lib/Reference/BingReferenceProvider.php b/lib/Reference/BingReferenceProvider.php index 4dec182..7c446fc 100644 --- a/lib/Reference/BingReferenceProvider.php +++ b/lib/Reference/BingReferenceProvider.php @@ -24,6 +24,7 @@ namespace OCA\Osm\Reference; use OCA\Osm\AppInfo\Application; +use OCP\Collaboration\Reference\IPublicReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; use OCP\Collaboration\Reference\IReferenceProvider; @@ -32,7 +33,7 @@ use OCP\Config\IUserConfig; use OCP\IAppConfig; -class BingReferenceProvider implements IReferenceProvider { +class BingReferenceProvider implements IReferenceProvider, IPublicReferenceProvider { private const RICH_OBJECT_TYPE = Application::APP_ID . '_location'; @@ -60,6 +61,10 @@ public function matchReference(string $referenceText): bool { return $this->getCoordinates($referenceText) !== null; } + public function resolveReferencePublic(string $referenceText, string $sharingToken): ?IReference { + return $this->resolveReference($referenceText); + } + /** * @inheritDoc */ @@ -154,6 +159,13 @@ public function getCacheKey(string $referenceId): ?string { return $referenceId; } + /** + * @inheritDoc + */ + public function getCacheKeyPublic(string $referenceId, string $sharingToken): ?string { + return null; + } + /** * @param string $userId * @return void diff --git a/lib/Reference/DuckduckgoReferenceProvider.php b/lib/Reference/DuckduckgoReferenceProvider.php index 5319486..b2d635e 100644 --- a/lib/Reference/DuckduckgoReferenceProvider.php +++ b/lib/Reference/DuckduckgoReferenceProvider.php @@ -24,6 +24,7 @@ namespace OCA\Osm\Reference; use OCA\Osm\AppInfo\Application; +use OCP\Collaboration\Reference\IPublicReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; use OCP\Collaboration\Reference\IReferenceProvider; @@ -32,7 +33,7 @@ use OCP\Config\IUserConfig; use OCP\IAppConfig; -class DuckduckgoReferenceProvider implements IReferenceProvider { +class DuckduckgoReferenceProvider implements IReferenceProvider, IPublicReferenceProvider { private const RICH_OBJECT_TYPE = Application::APP_ID . '_location'; @@ -60,6 +61,10 @@ public function matchReference(string $referenceText): bool { return $this->getCoordinates($referenceText) !== null; } + public function resolveReferencePublic(string $referenceText, string $sharingToken): ?IReference { + return $this->resolveReference($referenceText); + } + /** * @inheritDoc */ @@ -121,6 +126,13 @@ public function getCacheKey(string $referenceId): ?string { return $referenceId; } + /** + * @inheritDoc + */ + public function getCacheKeyPublic(string $referenceId, string $sharingToken): ?string { + return null; + } + /** * @param string $userId * @return void diff --git a/lib/Reference/GoogleMapsReferenceProvider.php b/lib/Reference/GoogleMapsReferenceProvider.php index 174db90..9cefd99 100644 --- a/lib/Reference/GoogleMapsReferenceProvider.php +++ b/lib/Reference/GoogleMapsReferenceProvider.php @@ -26,6 +26,7 @@ use OCA\Osm\AppInfo\Application; use OCA\Osm\Service\OsmAPIService; use OCA\Osm\Service\UtilsService; +use OCP\Collaboration\Reference\IPublicReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; use OCP\Collaboration\Reference\IReferenceProvider; @@ -36,7 +37,7 @@ use OCP\IURLGenerator; -class GoogleMapsReferenceProvider implements IReferenceProvider { +class GoogleMapsReferenceProvider implements IReferenceProvider, IPublicReferenceProvider { private const RICH_OBJECT_TYPE = Application::APP_ID . '_location'; @@ -67,6 +68,10 @@ public function matchReference(string $referenceText): bool { return $this->getCoordinates($referenceText) !== null; } + public function resolveReferencePublic(string $referenceText, string $sharingToken): ?IReference { + return $this->resolveReference($referenceText); + } + /** * @inheritDoc */ @@ -250,6 +255,13 @@ public function getCacheKey(string $referenceId): ?string { return $referenceId; } + /** + * @inheritDoc + */ + public function getCacheKeyPublic(string $referenceId, string $sharingToken): ?string { + return null; + } + /** * @param string $userId * @return void diff --git a/lib/Reference/HereMapsReferenceProvider.php b/lib/Reference/HereMapsReferenceProvider.php index 7672906..b2ac515 100644 --- a/lib/Reference/HereMapsReferenceProvider.php +++ b/lib/Reference/HereMapsReferenceProvider.php @@ -25,6 +25,7 @@ use OCA\Osm\AppInfo\Application; use OCA\Osm\Service\OsmAPIService; +use OCP\Collaboration\Reference\IPublicReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; use OCP\Collaboration\Reference\IReferenceProvider; @@ -35,7 +36,7 @@ use OCP\IURLGenerator; -class HereMapsReferenceProvider implements IReferenceProvider { +class HereMapsReferenceProvider implements IReferenceProvider, IPublicReferenceProvider { private const RICH_OBJECT_TYPE = Application::APP_ID . '_location'; @@ -65,6 +66,10 @@ public function matchReference(string $referenceText): bool { return $this->getCoordinates($referenceText) !== null; } + public function resolveReferencePublic(string $referenceText, string $sharingToken): ?IReference { + return $this->resolveReference($referenceText); + } + /** * @inheritDoc */ @@ -175,6 +180,13 @@ public function getCacheKey(string $referenceId): ?string { return $referenceId; } + /** + * @inheritDoc + */ + public function getCacheKeyPublic(string $referenceId, string $sharingToken): ?string { + return null; + } + /** * @param string $userId * @return void diff --git a/lib/Reference/OsmLocationReferenceProvider.php b/lib/Reference/OsmLocationReferenceProvider.php index 8a4904b..8024ebc 100644 --- a/lib/Reference/OsmLocationReferenceProvider.php +++ b/lib/Reference/OsmLocationReferenceProvider.php @@ -26,6 +26,7 @@ use OCA\Osm\AppInfo\Application; use OCA\Osm\Service\OsmAPIService; use OCA\Osm\Service\UtilsService; +use OCP\Collaboration\Reference\IPublicReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; use OCP\Collaboration\Reference\IReferenceProvider; @@ -36,7 +37,7 @@ use OCP\IURLGenerator; -class OsmLocationReferenceProvider implements IReferenceProvider { +class OsmLocationReferenceProvider implements IReferenceProvider, IPublicReferenceProvider { private const RICH_OBJECT_TYPE = Application::APP_ID . '_location'; @@ -67,6 +68,10 @@ public function matchReference(string $referenceText): bool { return $this->getCoordinates($referenceText) !== null || $this->getLocationTypeId($referenceText) !== null; } + public function resolveReferencePublic(string $referenceText, string $sharingToken): ?IReference { + return $this->resolveReference($referenceText); + } + /** * @inheritDoc */ @@ -187,6 +192,13 @@ public function getCacheKey(string $referenceId): ?string { return $referenceId; } + /** + * @inheritDoc + */ + public function getCacheKeyPublic(string $referenceId, string $sharingToken): ?string { + return null; + } + /** * @param string $userId * @return void diff --git a/lib/Reference/OsmPointReferenceProvider.php b/lib/Reference/OsmPointReferenceProvider.php index bbadbe3..4ec23e5 100644 --- a/lib/Reference/OsmPointReferenceProvider.php +++ b/lib/Reference/OsmPointReferenceProvider.php @@ -27,6 +27,7 @@ use OCA\Osm\Service\OsmAPIService; use OCA\Osm\Service\UtilsService; use OCP\Collaboration\Reference\ADiscoverableReferenceProvider; +use OCP\Collaboration\Reference\IPublicReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; use OCP\Collaboration\Reference\ISearchableReferenceProvider; @@ -38,7 +39,7 @@ use OCP\IURLGenerator; -class OsmPointReferenceProvider extends ADiscoverableReferenceProvider implements ISearchableReferenceProvider { +class OsmPointReferenceProvider extends ADiscoverableReferenceProvider implements ISearchableReferenceProvider, IPublicReferenceProvider { private const RICH_OBJECT_TYPE = Application::APP_ID . '_location'; @@ -107,6 +108,10 @@ public function matchReference(string $referenceText): bool { return $this->getCoordinates($referenceText) !== null; } + public function resolveReferencePublic(string $referenceText, string $sharingToken): ?IReference { + return $this->resolveReference($referenceText); + } + /** * @inheritDoc */ @@ -298,6 +303,13 @@ public function getCacheKey(string $referenceId): ?string { return $referenceId; } + /** + * @inheritDoc + */ + public function getCacheKeyPublic(string $referenceId, string $sharingToken): ?string { + return null; + } + /** * @param string $userId * @return void diff --git a/lib/Reference/OsmRouteReferenceProvider.php b/lib/Reference/OsmRouteReferenceProvider.php index 2ad38e1..26a59e9 100644 --- a/lib/Reference/OsmRouteReferenceProvider.php +++ b/lib/Reference/OsmRouteReferenceProvider.php @@ -26,6 +26,7 @@ use OCA\Osm\AppInfo\Application; use OCA\Osm\Service\RoutingService; use OCP\Collaboration\Reference\ADiscoverableReferenceProvider; +use OCP\Collaboration\Reference\IPublicReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; use OCP\Collaboration\Reference\LinkReferenceProvider; @@ -36,7 +37,7 @@ use OCP\IL10N; use OCP\IURLGenerator; -class OsmRouteReferenceProvider extends ADiscoverableReferenceProvider { +class OsmRouteReferenceProvider extends ADiscoverableReferenceProvider implements IPublicReferenceProvider { private const RICH_OBJECT_TYPE = Application::APP_ID . '_route'; @@ -97,6 +98,10 @@ public function matchReference(string $referenceText): bool { return $this->getLinkInfo($referenceText) !== null; } + public function resolveReferencePublic(string $referenceText, string $sharingToken): ?IReference { + return $this->resolveReference($referenceText); + } + /** * @inheritDoc */ @@ -323,6 +328,13 @@ public function getCacheKey(string $referenceId): ?string { return $referenceId; } + /** + * @inheritDoc + */ + public function getCacheKeyPublic(string $referenceId, string $sharingToken): ?string { + return null; + } + /** * @param string $userId * @return void From 0bd9262d6ff2b9b2ccaaa3b31bd50b87eb77bb35 Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 27 Mar 2026 12:42:00 +0100 Subject: [PATCH 3/5] remove default maptiler key, always fallback to osmRaster when no key is set, do not add vector styles when no key is set Signed-off-by: Julien Veyssier --- lib/AppInfo/Application.php | 1 - lib/Listener/OsmReferenceListener.php | 4 ++-- src/components/map/MaplibreMap.vue | 11 ++++++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index effc634..63c336e 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -40,7 +40,6 @@ class Application extends App implements IBootstrap { public const APP_ID = 'integration_openstreetmap'; public const OSM_URL = 'https://www.openstreetmap.org'; - public const DEFAULT_MAPTILER_API_KEY = 'get_your_own_OpIi9ZULNHzrESv6T2vL'; public const DEFAULT_SEARCH_LOCATION_ENABLED_VALUE = '0'; public const DEFAULT_PROXY_OSM_VALUE = '1'; diff --git a/lib/Listener/OsmReferenceListener.php b/lib/Listener/OsmReferenceListener.php index 4795185..1fd1519 100644 --- a/lib/Listener/OsmReferenceListener.php +++ b/lib/Listener/OsmReferenceListener.php @@ -50,7 +50,7 @@ public function handle(Event $event): void { return; } - $maptilerApiKey = $this->appConfig->getValueString(Application::APP_ID, 'maptiler_api_key', Application::DEFAULT_MAPTILER_API_KEY) ?: Application::DEFAULT_MAPTILER_API_KEY; + $maptilerApiKey = $this->appConfig->getValueString(Application::APP_ID, 'maptiler_api_key'); $userConfig = [ 'maptiler_api_key' => $maptilerApiKey, ]; @@ -60,7 +60,7 @@ public function handle(Event $event): void { if ($this->userId === null) { $this->initialState->provideInitialState('prefer-osm-frame', false); $this->initialState->provideInitialState('proxy-map-requests', false); - if ($maptilerApiKey === Application::DEFAULT_MAPTILER_API_KEY) { + if ($maptilerApiKey === '') { $this->initialState->provideInitialState('last-map-state', [ 'mapStyle' => 'osmRaster', ]); diff --git a/src/components/map/MaplibreMap.vue b/src/components/map/MaplibreMap.vue index a7630cf..747f9e9 100644 --- a/src/components/map/MaplibreMap.vue +++ b/src/components/map/MaplibreMap.vue @@ -79,7 +79,7 @@ export default { }, mapStyle: { type: String, - default: 'streets', + default: 'osmRaster', }, area: { type: Object, @@ -192,11 +192,16 @@ export default { initMap() { const apiKey = this.apiKeys.maptiler_api_key // tile servers and styles + const vectorStyles = apiKey ? getVectorStyles(apiKey) : {} this.styles = { - ...getVectorStyles(apiKey), + ...vectorStyles, ...getRasterTileServers(apiKey), } - const restoredStyleKey = Object.keys(this.styles).includes(this.mapStyle) ? this.mapStyle : 'streets' + const restoredStyleKey = Object.keys(this.styles).includes(this.mapStyle) + ? this.mapStyle + : apiKey + ? 'streets' + : 'osmRaster' const restoredStyleObj = this.styles[restoredStyleKey] this.$emit('update:mapStyle', restoredStyleKey) From 8f554ff871de8490e5a049e09ca7698db276c68e Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 27 Mar 2026 12:55:47 +0100 Subject: [PATCH 4/5] hide all terrain stuff if no api key set Signed-off-by: Julien Veyssier --- src/components/map/MaplibreMap.vue | 35 ++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/components/map/MaplibreMap.vue b/src/components/map/MaplibreMap.vue index 747f9e9..5cceb6c 100644 --- a/src/components/map/MaplibreMap.vue +++ b/src/components/map/MaplibreMap.vue @@ -122,6 +122,7 @@ export default { globeControl: null, myUseGlobe: this.useGlobe, apiKeys: loadState('integration_openstreetmap', 'api-keys'), + proxyMapRequests: loadState('integration_openstreetmap', 'proxy-map-requests', false), maptilerLogoUrl: loadState('integration_openstreetmap', 'proxy-map-requests', false) ? generateUrl('/apps/integration_openstreetmap/maptiler/resources/logo.svg') : 'https://api.maptiler.com/resources/logo.svg', @@ -129,6 +130,9 @@ export default { }, computed: { + hasMaptilerApiKey() { + return !!this.apiKeys?.maptiler_api_key + }, }, watch: { @@ -284,9 +288,11 @@ export default { this.map.addControl(tileControl, 'top-right') this.map.addControl(fullscreenControl, 'top-right') - this.terrainControl = new TerrainControl() - this.terrainControl.on('toggleTerrain', this.toggleTerrain) - this.map.addControl(this.terrainControl, 'top-right') + if (this.hasMaptilerApiKey) { + this.terrainControl = new TerrainControl() + this.terrainControl.on('toggleTerrain', this.toggleTerrain) + this.map.addControl(this.terrainControl, 'top-right') + } this.globeControl = new GlobeControl() this.globeControl.on('toggleGlobe', this.toggleGlobe) @@ -313,7 +319,9 @@ export default { this.map.on('load', () => { this.loadImages() - this.terrainControl.updateTerrainIcon(this.myUseTerrain) + if (this.hasMaptilerApiKey) { + this.terrainControl.updateTerrainIcon(this.myUseTerrain) + } this.globeControl.updateGlobeIcon(this.myUseGlobe) setTimeout(() => { @@ -369,11 +377,14 @@ export default { // re render the layers this.mapLoaded = false this.loadImages() - if (this.myUseTerrain) { + if (this.hasMaptilerApiKey && this.myUseTerrain) { this.enableTerrain() } }, toggleTerrain() { + if (!this.hasMaptilerApiKey) { + return + } this.myUseTerrain = !this.myUseTerrain this.$emit('update:useTerrain', this.myUseTerrain) if (this.myUseTerrain) { @@ -384,6 +395,9 @@ export default { this.terrainControl.updateTerrainIcon(this.myUseTerrain) }, enableTerrain() { + if (!this.hasMaptilerApiKey) { + return + } this.addTerrainSource() this.map.setTerrain({ source: 'terrain', @@ -391,17 +405,24 @@ export default { }) }, disableTerrain() { + if (!this.hasMaptilerApiKey) { + return + } this.map.setTerrain() }, addTerrainSource() { + if (!this.hasMaptilerApiKey) { + return + } if (this.map.getSource('terrain')) { return } const apiKey = this.apiKeys.maptiler_api_key this.map.addSource('terrain', { type: 'raster-dem', - // url: 'https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=' + apiKey, - url: generateUrl('/apps/integration_openstreetmap/maptiler/tiles/terrain-rgb-v2/tiles.json?key=' + apiKey), + url: this.proxyMapRequests + ? generateUrl('/apps/integration_openstreetmap/maptiler/tiles/terrain-rgb-v2/tiles.json?key=' + apiKey) + : 'https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=' + apiKey, }) }, handleMapEvents() { From b4060464063d4506556e1980e0ab95a64b032d36 Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 27 Mar 2026 13:12:22 +0100 Subject: [PATCH 5/5] add referer header in map requests now enforced by OSM Signed-off-by: Julien Veyssier --- src/components/map/MaplibreMap.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/map/MaplibreMap.vue b/src/components/map/MaplibreMap.vue index 5cceb6c..1879fda 100644 --- a/src/components/map/MaplibreMap.vue +++ b/src/components/map/MaplibreMap.vue @@ -219,6 +219,12 @@ export default { // bounds, maxPitch: 75, maxZoom: restoredStyleObj.maxzoom ? (restoredStyleObj.maxzoom - 0.01) : DEFAULT_MAP_MAX_ZOOM, + transformRequest: (url, resourceType) => { + return { + url, + referrerPolicy: 'origin-when-cross-origin', + } + }, } this.map = new Map(mapOptions) if (this.bbox) {