From c4d1390270291c12bb31af6f8276f9b2f6c9696e Mon Sep 17 00:00:00 2001 From: Martin Raifer Date: Tue, 10 Oct 2023 15:50:11 +0200 Subject: [PATCH] use api.osm.org url for OSM API calls see https://github.com/openstreetmap/operations/issues/951 --- API.md | 3 +- config/id.js | 1 + modules/services/osm.js | 73 +++++++++++++++++++++++---------------- test/spec/services/osm.js | 17 +++++++++ 4 files changed, 64 insertions(+), 30 deletions(-) diff --git a/API.md b/API.md index 30d3ea7c2a..723b9aaa14 100644 --- a/API.md +++ b/API.md @@ -106,7 +106,8 @@ In addition, the following parameters are available as **URL query parameters**: Environment variables or a dotenv file can be used to configure certain aspects of iD at build time. -* __`ID_API_CONNECTION_URL`__, __`ID_API_CONNECTION_CLIENT_ID`__, __`ID_API_CONNECTION_CLIENT_SECRET`__ - Custom [Oauth2](https://wiki.openstreetmap.org/wiki/OAuth#OAuth_2.0_2) connection details to an OSM API server. +* __`ID_API_CONNECTION_URL`__, __`ID_API_CONNECTION_CLIENT_ID`__, __`ID_API_CONNECTION_CLIENT_SECRET`__ - Custom [OAuth2](https://wiki.openstreetmap.org/wiki/OAuth#OAuth_2.0_2) connection details to an OSM API server. +* __`ID_API_CONNECTION_API_URL`__ Optional url to use for OSM API calls aftern the initial authentication is complete when using a custom OAuth2 connection (see above). If unspecified, `ID_API_CONNECTION_URL` will be used for both the authentication and subsequent API calls. * __`ID_API_CONNECTION`__ - Either `live` or `dev`, if only either one should be made offered for editing. * __`ID_PRESETS_CDN_URL`__ - The URL where iD should fetch it's tagging presets from. Needs to point to a CORS enabled web server which is serving the `package.json` and `dist` folder of a repository built on [`@ideditor/schema-builder`](https://github.com/ideditor/schema-builder). * __`ENV__ID_OCI_CDN_URL`__ - URL to a hosted version of the [osm-community-index](https://github.com/osmlab/osm-community-index) diff --git a/config/id.js b/config/id.js index 7f5625f3db..5c8287ffbf 100644 --- a/config/id.js +++ b/config/id.js @@ -14,6 +14,7 @@ const nsiCdnUrl = ENV__ID_NSI_CDN_URL const defaultOsmApiConnections = { live: { url: 'https://www.openstreetmap.org', + apiUrl: 'https://api.openstreetmap.org', client_id: '0tmNTmd0Jo1dQp4AUmMBLtGiD9YpMuXzHefitcuVStc', client_secret: 'BTlNrNxIPitHdL4sP2clHw5KLoee9aKkA7dQbc0Bj7Q' }, diff --git a/modules/services/osm.js b/modules/services/osm.js index 10646ad0fa..ca435ebdb1 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -17,6 +17,7 @@ var tiler = utilTiler(); var dispatch = d3_dispatch('apiStatusChange', 'authLoading', 'authDone', 'change', 'loading', 'loaded', 'loadedNotes'); var urlroot = osmApiConnections[0].url; +var apiUrlroot = osmApiConnections[0].apiUrl || urlroot; var redirectPath = window.location.origin + window.location.pathname; var oauth = osmAuth({ url: urlroot, @@ -669,7 +670,11 @@ export default { } if (this.authenticated()) { - return oauth.xhr({ method: 'GET', path: path }, done); + return oauth.xhr({ + method: 'GET', + prefix: false, + path: urlroot + path + }, done); } else { var url = urlroot + path; var controller = new AbortController(); @@ -796,7 +801,8 @@ export default { } else { // Open a new changeset.. var options = { method: 'PUT', - path: '/api/0.6/changeset/create', + prefix: false, + path: apiUrlroot + '/api/0.6/changeset/create', headers: { 'Content-Type': 'text/xml' }, content: JXON.stringify(changeset.asJXON()) }; @@ -817,7 +823,8 @@ export default { // Upload the changeset.. var options = { method: 'POST', - path: '/api/0.6/changeset/' + changesetID + '/upload', + prefix: false, + path: apiUrlroot + '/api/0.6/changeset/' + changesetID + '/upload', headers: { 'Content-Type': 'text/xml' }, content: JXON.stringify(changeset.osmChangeJXON(changes)) }; @@ -843,7 +850,8 @@ export default { // Still attempt to close changeset, but ignore response because #2667 oauth.xhr({ method: 'PUT', - path: '/api/0.6/changeset/' + changeset.id + '/close', + prefix: false, + path: apiUrlroot + '/api/0.6/changeset/' + changeset.id + '/close', headers: { 'Content-Type': 'text/xml' } }, function() { return true; }); } @@ -873,10 +881,11 @@ export default { } utilArrayChunk(toLoad, 150).forEach(function(arr) { - oauth.xhr( - { method: 'GET', path: '/api/0.6/users.json?users=' + arr.join() }, - wrapcb(this, done, _connectionID) - ); + oauth.xhr({ + method: 'GET', + prefix: false, + path: apiUrlroot + '/api/0.6/users.json?users=' + arr.join() + }, wrapcb(this, done, _connectionID)); }.bind(this)); function done(err, payload) { @@ -899,10 +908,11 @@ export default { return callback(undefined, _userCache.user[uid]); } - oauth.xhr( - { method: 'GET', path: '/api/0.6/user/' + uid + '.json' }, - wrapcb(this, done, _connectionID) - ); + oauth.xhr({ + method: 'GET', + prefix: false, + path: apiUrlroot + '/api/0.6/user/' + uid + '.json' + }, wrapcb(this, done, _connectionID)); function done(err, payload) { if (err) return callback(err); @@ -923,10 +933,11 @@ export default { return callback(undefined, _userDetails); } - oauth.xhr( - { method: 'GET', path: '/api/0.6/user/details.json' }, - wrapcb(this, done, _connectionID) - ); + oauth.xhr({ + method: 'GET', + prefix: false, + path: apiUrlroot + '/api/0.6/user/details.json' + }, wrapcb(this, done, _connectionID)); function done(err, payload) { if (err) return callback(err); @@ -956,10 +967,11 @@ export default { function gotDetails(err, user) { if (err) { return callback(err); } - oauth.xhr( - { method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, - wrapcb(this, done, _connectionID) - ); + oauth.xhr({ + method: 'GET', + prefix: false, + path: apiUrlroot + '/api/0.6/changesets?user=' + user.id + }, wrapcb(this, done, _connectionID)); } function done(err, xml) { @@ -981,7 +993,7 @@ export default { // Fetch the status of the OSM API // GET /api/capabilities status: function(callback) { - var url = urlroot + '/api/capabilities'; + var url = apiUrlroot + '/api/capabilities'; var errback = wrapcb(this, done, _connectionID); d3_xml(url) .then(function(data) { errback(null, data); }) @@ -1195,10 +1207,11 @@ export default { var path = '/api/0.6/notes?' + utilQsString({ lon: note.loc[0], lat: note.loc[1], text: comment }); - _noteCache.inflightPost[note.id] = oauth.xhr( - { method: 'POST', path: path }, - wrapcb(this, done, _connectionID) - ); + _noteCache.inflightPost[note.id] = oauth.xhr({ + method: 'POST', + prefix: false, + path: urlroot + path + }, wrapcb(this, done, _connectionID)); function done(err, xml) { @@ -1247,10 +1260,11 @@ export default { path += '?' + utilQsString({ text: note.newComment }); } - _noteCache.inflightPost[note.id] = oauth.xhr( - { method: 'POST', path: path }, - wrapcb(this, done, _connectionID) - ); + _noteCache.inflightPost[note.id] = oauth.xhr({ + method: 'POST', + prefix: false, + path: urlroot + path + }, wrapcb(this, done, _connectionID)); function done(err, xml) { @@ -1289,6 +1303,7 @@ export default { switch: function(newOptions) { urlroot = newOptions.url; + apiUrlroot = newOptions.apiUrl || urlroot; // Copy the existing options, but omit 'access_token'. // (if we did preauth, access_token won't work on a different server) diff --git a/test/spec/services/osm.js b/test/spec/services/osm.js index bad227032a..4b02571d37 100644 --- a/test/spec/services/osm.js +++ b/test/spec/services/osm.js @@ -263,6 +263,23 @@ describe('iD.serviceOsm', function () { done(); }); }); + + it('uses apiUrl', function(done) { + fetchMock.mock('https://api.openstreetmap.org' + path, { + body: response, + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + + connection.switch({ url: 'https://api.openstreetmap.org' }); + + connection.loadFromAPI(path, function (err) { + expect(err).to.not.be.ok; + expect(fetchMock.calls().length).to.eql(1); + expect(fetchMock.calls()[0][0]).to.eql('https://api.openstreetmap.org' + path); + done(); + }); + }); });