From 78455ccc4072f61b682dcff7e26c08ea77097cee Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Thu, 19 Mar 2026 00:24:17 +0000 Subject: [PATCH] fix(maps): respect request protocol for reverse proxy HTTPS support --- admin/app/controllers/maps_controller.ts | 2 +- admin/app/services/map_service.ts | 14 +++++++------- admin/inertia/components/maps/MapComponent.tsx | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/admin/app/controllers/maps_controller.ts b/admin/app/controllers/maps_controller.ts index 8290d45..54f0e8f 100644 --- a/admin/app/controllers/maps_controller.ts +++ b/admin/app/controllers/maps_controller.ts @@ -83,7 +83,7 @@ export default class MapsController { }) } - const styles = await this.mapService.generateStylesJSON(request.host()) + const styles = await this.mapService.generateStylesJSON(request.host(), request.protocol()) return response.json(styles) } diff --git a/admin/app/services/map_service.ts b/admin/app/services/map_service.ts index 6f7cbfd..beb74b2 100644 --- a/admin/app/services/map_service.ts +++ b/admin/app/services/map_service.ts @@ -260,7 +260,7 @@ export class MapService implements IMapService { } } - async generateStylesJSON(host: string | null = null): Promise { + async generateStylesJSON(host: string | null = null, protocol: string = 'http'): Promise { if (!(await this.checkBaseAssetsExist())) { throw new Error('Base map assets are missing from storage/maps') } @@ -281,8 +281,8 @@ export class MapService implements IMapService { * e.g. user is accessing from "example.com", but we would by default generate "localhost:8080/..." so maps would * fail to load. */ - const sources = this.generateSourcesArray(host, regions) - const baseUrl = this.getPublicFileBaseUrl(host, this.basemapsAssetsDir) + const sources = this.generateSourcesArray(host, regions, protocol) + const baseUrl = this.getPublicFileBaseUrl(host, this.basemapsAssetsDir, protocol) const styles = await this.generateStylesFile( rawStyles, @@ -342,9 +342,9 @@ export class MapService implements IMapService { return await listDirectoryContentsRecursive(this.baseDirPath) } - private generateSourcesArray(host: string | null, regions: FileEntry[]): BaseStylesFile['sources'][] { + private generateSourcesArray(host: string | null, regions: FileEntry[], protocol: string = 'http'): BaseStylesFile['sources'][] { const sources: BaseStylesFile['sources'][] = [] - const baseUrl = this.getPublicFileBaseUrl(host, 'pmtiles') + const baseUrl = this.getPublicFileBaseUrl(host, 'pmtiles', protocol) for (const region of regions) { if (region.type === 'file' && region.name.endsWith('.pmtiles')) { @@ -433,7 +433,7 @@ export class MapService implements IMapService { /* * Gets the appropriate public URL for a map asset depending on environment */ - private getPublicFileBaseUrl(specifiedHost: string | null, childPath: string): string { + private getPublicFileBaseUrl(specifiedHost: string | null, childPath: string, protocol: string = 'http'): string { function getHost() { try { const localUrlRaw = env.get('URL') @@ -447,7 +447,7 @@ export class MapService implements IMapService { } const host = specifiedHost || getHost() - const withProtocol = host.startsWith('http') ? host : `http://${host}` + const withProtocol = host.startsWith('http') ? host : `${protocol}://${host}` const baseUrlPath = process.env.NODE_ENV === 'production' ? childPath : urlJoin(this.mapStoragePath, childPath) diff --git a/admin/inertia/components/maps/MapComponent.tsx b/admin/inertia/components/maps/MapComponent.tsx index dfcd6e7..5cc2d3b 100644 --- a/admin/inertia/components/maps/MapComponent.tsx +++ b/admin/inertia/components/maps/MapComponent.tsx @@ -23,7 +23,7 @@ export default function MapComponent() { width: '100%', height: '100vh', }} - mapStyle={`http://${window.location.hostname}:${window.location.port}/api/maps/styles`} + mapStyle={`${window.location.protocol}//${window.location.hostname}:${window.location.port}/api/maps/styles`} mapLib={maplibregl} initialViewState={{ longitude: -101,