Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions modules/carto/src/api/parse-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
negateAccessor,
getMaxMarkerSize
} from './layer-map';
import {assert} from '../utils';
import {assert, getAuthFetchOptions} from '../utils';
import {KeplerMapConfig, MapDataset, MapLayerConfig, VisualChannels} from './types';

export type ParseMapResult = {
Expand Down Expand Up @@ -365,8 +365,8 @@ function createChannelProps(
return result;
}

function createLoadOptions(accessToken: string) {
function createLoadOptions(accessToken: string | undefined) {
return {
loadOptions: {core: {fetch: {headers: {Authorization: `Bearer ${accessToken}`}}}}
loadOptions: {core: {fetch: getAuthFetchOptions(accessToken)}}
};
}
3 changes: 2 additions & 1 deletion modules/carto/src/layers/cluster-tile-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/* eslint-disable no-shadow */

import {GeoJsonLayer, GeoJsonLayerProps} from '@deck.gl/layers';
import {getAuthFetchOptions} from '../utils';
import {
TileLayer,
_Tile2DHeader as Tile2DHeader,
Expand Down Expand Up @@ -292,7 +293,7 @@ export default class ClusterTileLayer<
const tileJSON = this.props.data as TilejsonResult;
const scheme = tileJSON && 'scheme' in tileJSON ? tileJSON.scheme : 'quadbin';
return mergeLoadOptions(super.getLoadOptions(), {
fetch: {headers: {Authorization: `Bearer ${tileJSON.accessToken}`}},
fetch: getAuthFetchOptions(tileJSON.accessToken),
cartoSpatialTile: {scheme}
});
}
Expand Down
3 changes: 2 additions & 1 deletion modules/carto/src/layers/h3-tile-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Copyright (c) vis.gl contributors

import {CompositeLayer, CompositeLayerProps, DefaultProps} from '@deck.gl/core';
import {getAuthFetchOptions} from '../utils';
import {H3HexagonLayer, H3HexagonLayerProps} from '@deck.gl/geo-layers';
import H3Tileset2D, {getHexagonResolution} from './h3-tileset-2d';
import SpatialIndexTileLayer, {SpatialIndexTileLayerProps} from './spatial-index-tile-layer';
Expand Down Expand Up @@ -49,7 +50,7 @@ export default class H3TileLayer<DataT = any, ExtraPropsT extends {} = {}> exten
getLoadOptions(): any {
const tileJSON = this.props.data as TilejsonResult;
return mergeLoadOptions(super.getLoadOptions(), {
fetch: {headers: {Authorization: `Bearer ${tileJSON.accessToken}`}},
fetch: getAuthFetchOptions(tileJSON.accessToken),
cartoSpatialTile: {scheme: 'h3'}
});
}
Expand Down
3 changes: 2 additions & 1 deletion modules/carto/src/layers/quadbin-tile-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Copyright (c) vis.gl contributors

import {CompositeLayer, CompositeLayerProps, DefaultProps} from '@deck.gl/core';
import {getAuthFetchOptions} from '../utils';
import QuadbinLayer, {QuadbinLayerProps} from './quadbin-layer';
import QuadbinTileset2D from './quadbin-tileset-2d';
import SpatialIndexTileLayer, {SpatialIndexTileLayerProps} from './spatial-index-tile-layer';
Expand Down Expand Up @@ -45,7 +46,7 @@ export default class QuadbinTileLayer<
getLoadOptions(): any {
const tileJSON = this.props.data as TilejsonResult;
return mergeLoadOptions(super.getLoadOptions(), {
fetch: {headers: {Authorization: `Bearer ${tileJSON.accessToken}`}},
fetch: getAuthFetchOptions(tileJSON.accessToken),
cartoSpatialTile: {scheme: 'quadbin'}
});
}
Expand Down
3 changes: 2 additions & 1 deletion modules/carto/src/layers/raster-tile-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
LayersList
} from '@deck.gl/core';
import RasterLayer, {RasterLayerProps} from './raster-layer';
import {getAuthFetchOptions} from '../utils';
import QuadbinTileset2D from './quadbin-tileset-2d';
import type {TilejsonResult} from '@carto/api-client';
import {TilejsonPropType, mergeLoadOptions} from './utils';
Expand Down Expand Up @@ -66,7 +67,7 @@ export default class RasterTileLayer<
getLoadOptions(): any {
const tileJSON = this.props.data as TilejsonResult;
return mergeLoadOptions(super.getLoadOptions(), {
fetch: {headers: {Authorization: `Bearer ${tileJSON.accessToken}`}}
fetch: getAuthFetchOptions(tileJSON.accessToken)
});
}

Expand Down
4 changes: 2 additions & 2 deletions modules/carto/src/layers/vector-tile-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type {TilejsonResult} from '@carto/api-client';
import {TilejsonPropType, mergeLoadOptions, mergeBoundaryData} from './utils';
import {DEFAULT_TILE_SIZE} from '../constants';
import {createPointsFromLines, createPointsFromPolygons} from './label-utils';
import {createEmptyBinary} from '../utils';
import {createEmptyBinary, getAuthFetchOptions} from '../utils';
import PointLabelLayer from './point-label-layer';

const MVT_BBOX: GeoBoundingBox = {west: 0, east: 1, south: 0, north: 1};
Expand Down Expand Up @@ -89,7 +89,7 @@ export default class VectorTileLayer<
getLoadOptions(): any {
const tileJSON = this.props.data as TilejsonResult;
return mergeLoadOptions(super.getLoadOptions(), {
fetch: {headers: {Authorization: `Bearer ${tileJSON.accessToken}`}},
fetch: getAuthFetchOptions(tileJSON.accessToken),
gis: {format: 'binary'} // Use binary for MVT loading
});
}
Expand Down
17 changes: 17 additions & 0 deletions modules/carto/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,20 @@ export function copyNumericProps(
targetProps[prop].value[targetIndex] = sourceProps[prop].value[sourceIndex];
});
}

/**
* Fetch options carrying the CARTO Authorization header, or none when no
* access token is present — e.g. a source created with the api-client's
* session auth mode, where tile URLs are same-origin and authenticated by a
* cookie. Emitting `Bearer undefined` would defeat such server-side session
* handling, which engages only when the Authorization header is absent.
*/
export function getAuthFetchOptions(accessToken: string | undefined): {
headers?: Record<string, string>;
credentials?: RequestCredentials;
} {
if (!accessToken) {
return {credentials: 'same-origin'};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve caller-supplied fetch credentials

When accessToken is absent, every CARTO tile layer passes this object into mergeLoadOptions(super.getLoadOptions(), ...); because credentials is a primitive value, it overwrites any loadOptions.fetch.credentials the application supplied. This breaks configurations that intentionally use credentials: 'include' for cross-origin cookie auth or credentials: 'omit' for public requests, even though the intended fix only needs to omit the Authorization header. Returning an empty fetch-options object in the no-token case would avoid clobbering user fetch settings.

Useful? React with 👍 / 👎.

}
return {headers: {Authorization: `Bearer ${accessToken}`}};
}