diff --git a/docs/config.rst b/docs/config.rst index 3bc1a5a..f18be8e 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -8,6 +8,9 @@ Example:: { "options": { + "auth": { + "keyName": "api_key" + }, "paths": { "root": "", "fonts": "fonts", @@ -58,6 +61,11 @@ Example:: ``options`` =========== +``auth`` +--------- + +Defines another name for the key query parameter in ``keyName``. Default is ``key``. + ``paths`` --------- diff --git a/src/serve_style.js b/src/serve_style.js index fb75ad8..a744697 100644 --- a/src/serve_style.js +++ b/src/serve_style.js @@ -11,13 +11,13 @@ const utils = require('./utils'); const httpTester = /^(http(s)?:)?\/\//; -const fixUrl = (req, url, publicUrl, opt_nokey) => { +const fixUrl = (req, url, publicUrl, opt_nokey, options) => { if (!url || (typeof url !== 'string') || url.indexOf('local://') !== 0) { return url; } const queryParams = []; - if (!opt_nokey && req.query.key) { - queryParams.unshift(`key=${encodeURIComponent(req.query.key)}`); + if (!opt_nokey && req.query[options.auth.keyName]) { + queryParams.unshift(`${options.auth.keyName}=${encodeURIComponent(req.query[options.auth.keyName])}`); } let query = ''; if (queryParams.length) { @@ -39,14 +39,14 @@ module.exports = { const styleJSON_ = clone(item.styleJSON); for (const name of Object.keys(styleJSON_.sources)) { const source = styleJSON_.sources[name]; - source.url = fixUrl(req, source.url, item.publicUrl); + source.url = fixUrl(req, source.url, item.publicUrl, false, options); } // mapbox-gl-js viewer cannot handle sprite urls with query if (styleJSON_.sprite) { - styleJSON_.sprite = fixUrl(req, styleJSON_.sprite, item.publicUrl, true); + styleJSON_.sprite = fixUrl(req, styleJSON_.sprite, item.publicUrl, false, options); } if (styleJSON_.glyphs) { - styleJSON_.glyphs = fixUrl(req, styleJSON_.glyphs, item.publicUrl, false); + styleJSON_.glyphs = fixUrl(req, styleJSON_.glyphs, item.publicUrl, false, options); } return res.send(styleJSON_); }); diff --git a/src/server.js b/src/server.js index 59de3cd..7ab50e8 100644 --- a/src/server.js +++ b/src/server.js @@ -69,6 +69,10 @@ function start(opts) { } const options = config.options || {}; + + options.auth = options.auth || {}; + options.auth.keyName = options.auth.keyName || 'key'; + const paths = options.paths || {}; options.paths = paths; paths.root = path.resolve( @@ -243,7 +247,9 @@ function start(opts) { app.get('/styles.json', (req, res, next) => { const result = []; - const query = req.query.key ? (`?key=${encodeURIComponent(req.query.key)}`) : ''; + const query = req.query[options.auth.keyName] + ? `?${options.auth.keyName}=${encodeURIComponent(req.query[options.auth.keyName])}` + : ''; for (const id of Object.keys(serving.styles)) { const styleJSON = serving.styles[id].styleJSON; result.push({ @@ -267,7 +273,7 @@ function start(opts) { } info.tiles = utils.getTileUrls(req, info.tiles, path, info.format, opts.publicUrl, { 'pbf': options.pbfAlias - }); + }, options); arr.push(info); } return arr; @@ -318,9 +324,12 @@ function start(opts) { data['server_version'] = `${packageJson.name} v${packageJson.version}`; data['public_url'] = opts.publicUrl || '/'; data['is_light'] = isLight; - data['key_query_part'] = - req.query.key ? `key=${encodeURIComponent(req.query.key)}&` : ''; - data['key_query'] = req.query.key ? `?key=${encodeURIComponent(req.query.key)}` : ''; + data['key_query_part'] = req.query[options.auth.keyName] + ? `${options.auth.keyName}=${encodeURIComponent(req.query[options.auth.keyName])}&` + : ''; + data['key_query'] = req.query[options.auth.keyName] + ? `?${options.auth.keyName}=${encodeURIComponent(req.query[options.auth.keyName])}` + : ''; if (template === 'wmts') res.set('Content-Type', 'text/xml'); return res.status(200).send(compiled(data)); }); @@ -347,7 +356,7 @@ function start(opts) { style.xyz_link = utils.getTileUrls( req, style.serving_rendered.tileJSON.tiles, - `styles/${id}`, style.serving_rendered.tileJSON.format, opts.publicUrl)[0]; + `styles/${id}`, style.serving_rendered.tileJSON.format, opts.publicUrl, null, options)[0]; } } const data = clone(serving.data || {}); @@ -368,7 +377,7 @@ function start(opts) { data_.xyz_link = utils.getTileUrls( req, tilejson.tiles, `data/${id}`, tilejson.format, opts.publicUrl, { 'pbf': options.pbfAlias - })[0]; + }, options)[0]; } if (data_.filesize) { let suffix = 'kB'; diff --git a/src/utils.js b/src/utils.js index 6037e20..fcfd43f 100644 --- a/src/utils.js +++ b/src/utils.js @@ -9,7 +9,7 @@ const glyphCompose = require('@mapbox/glyph-pbf-composite'); module.exports.getPublicUrl = (publicUrl, req) => publicUrl || `${req.protocol}://${req.headers.host}/`; -module.exports.getTileUrls = (req, domains, path, format, publicUrl, aliases) => { +module.exports.getTileUrls = (req, domains, path, format, publicUrl, aliases, options) => { if (domains) { if (domains.constructor === String && domains.length > 0) { @@ -37,10 +37,9 @@ module.exports.getTileUrls = (req, domains, path, format, publicUrl, aliases) => domains = [req.headers.host]; } - const key = req.query.key; const queryParams = []; - if (req.query.key) { - queryParams.push(`key=${encodeURIComponent(req.query.key)}`); + if (req.query[options.auth.keyName]) { + queryParams.push(`${options.auth.keyName}=${encodeURIComponent(req.query[options.auth.keyName])}`); } if (req.query.style) { queryParams.push(`style=${encodeURIComponent(req.query.style)}`);