diff --git a/CHANGELOG.md b/CHANGELOG.md index a10b998c0..f3f046d2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ _Breaking developer changes, which may affect downstream projects or sites that #### :newspaper: News * Drop legacy support for Internet Explorer 11 ([#8811]) +* Use OAuth2 for authentication with OSM API ([#9134], thanks [@bhousel] and [@dakotabenjamin]) #### :white_check_mark: Validation * Handle indoor features like buildings when checking for crossing ways ([#8944]) #### :bug: Bugfixes @@ -66,6 +67,7 @@ _Breaking developer changes, which may affect downstream projects or sites that #### Other * Redact more API tokens from custom imagery sources in changeset metadata tags ([#8976], thanks [@k-yle]) * New Bing imagery API key and limit tiles vintage API requests ([#9133], thanks [@mbrzakovic]) +* Change authentication #### :hammer: Development * Switch build system to [esbuild](https://esbuild.github.io/) for much faster builds ([#8774], thanks [@mbrzakovic] and [@bhousel]) * Upgrade dependencies: maki to `v7.1`, `fontawesome` to `v6.1`, `d3` to `v7.4`, `node-diff` to `v3.1`, `mocha` to `v9.2`, `svg-sprite` to `v1.5.4`, `marked` to `v4.0`, `temaki` to `v5.1`, `mapillary-js` to `v4.1` @@ -88,8 +90,9 @@ _Breaking developer changes, which may affect downstream projects or sites that [#9118]: https://github.com/openstreetmap/iD/issues/9118 [#9124]: https://github.com/openstreetmap/iD/pull/9124 [#9133]: https://github.com/openstreetmap/iD/pull/9133 +[#9134]: https://github.com/openstreetmap/iD/pull/9134 [@wcedmisten]: https://github.com/wcedmisten - +[@dakotabenjamin]: https://github.com/dakotabenjamin # 2.20.4 ##### 2022-Feb-03 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9695a3885..fe95e28ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -394,7 +394,7 @@ In your local copy, make a branch for this change using a descriptive branch nam Make your changes to source files under `modules/`. The `iD.js` and `iD.min.js` files in this project are autogenerated - don't edit them. -1. Try your change locally. Run `npm start` and visit `localhost:8080` in a browser. +1. Try your change locally. Run `npm start` and visit `http://127.0.0.1:8080` in a browser. 2. Run lint and tests with `npm test`. 3. If you feel like it, append a line describing your changes to the project's [changelog](https://github.com/openstreetmap/iD/blob/develop/CHANGELOG.md). 4. Commit your changes with an informative commit message. diff --git a/README.md b/README.md index 55ff0e433..66bf34e00 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ If you want to add in the full history later on, perhaps to run `git blame` or ` 2. Run `npm install` 3. Run `npm run all` 3. Run `npm start` -4. Open `http://localhost:8080/` in a web browser +4. Open `http://127.0.0.1:8080/` in a web browser For guidance on building a packaged version, running tests, and contributing to development, see [CONTRIBUTING.md](CONTRIBUTING.md). diff --git a/dist/index.html b/dist/index.html index d206b8a3c..673dcc29f 100644 --- a/dist/index.html +++ b/dist/index.html @@ -45,13 +45,13 @@ .assetPath('') .apiConnections([ { - 'urlroot': 'https://www.openstreetmap.org', - 'oauth_consumer_key': '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT', - 'oauth_secret': 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL' + url: 'https://www.openstreetmap.org', + client_id: '0tmNTmd0Jo1dQp4AUmMBLtGiD9YpMuXzHefitcuVStc', + client_secret: 'BTlNrNxIPitHdL4sP2clHw5KLoee9aKkA7dQbc0Bj7Q' }, { - 'urlroot': 'https://api06.dev.openstreetmap.org', - 'oauth_consumer_key': 'zwQZFivccHkLs3a8Rq5CoS412fE5aPCXDw9DZj7R', - 'oauth_secret': 'aMnOOCwExO2XYtRVWJ1bI9QOdqh1cay2UgpbhA6p' + url: 'https://api06.dev.openstreetmap.org', + client_id: 'Ee1wWJ6UlpERbF6BfTNOpwn0R8k_06mvMXdDUkeHMgw', + client_secret: 'OnfWFC-JkZNHyYdr_viNn_h_RTZXRslKcUxllOXqf5g' } ]) .containerNode(container); diff --git a/index.html b/index.html index 6b394ede8..dae23ef65 100644 --- a/index.html +++ b/index.html @@ -45,13 +45,13 @@ .assetPath('dist/') .apiConnections([ { - 'urlroot': 'https://www.openstreetmap.org', - 'oauth_consumer_key': '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT', - 'oauth_secret': 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL' + url: 'https://www.openstreetmap.org', + client_id: '0tmNTmd0Jo1dQp4AUmMBLtGiD9YpMuXzHefitcuVStc', + client_secret: 'BTlNrNxIPitHdL4sP2clHw5KLoee9aKkA7dQbc0Bj7Q' }, { - 'urlroot': 'https://api06.dev.openstreetmap.org', - 'oauth_consumer_key': 'zwQZFivccHkLs3a8Rq5CoS412fE5aPCXDw9DZj7R', - 'oauth_secret': 'aMnOOCwExO2XYtRVWJ1bI9QOdqh1cay2UgpbhA6p' + url: 'https://api06.dev.openstreetmap.org', + client_id: 'Ee1wWJ6UlpERbF6BfTNOpwn0R8k_06mvMXdDUkeHMgw', + client_secret: 'OnfWFC-JkZNHyYdr_viNn_h_RTZXRslKcUxllOXqf5g' } ]) .containerNode(container); @@ -67,4 +67,4 @@ } - + \ No newline at end of file diff --git a/modules/services/osm.js b/modules/services/osm.js index 6a1f80abc..aa47d180b 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -2,26 +2,30 @@ import _throttle from 'lodash-es/throttle'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { json as d3_json, xml as d3_xml } from 'd3-fetch'; - -import osmAuth from 'osm-auth'; +import { osmAuth } from 'osm-auth'; import RBush from 'rbush'; import { JXON } from '../util/jxon'; import { geoExtent, geoRawMercator, geoVecAdd, geoZoomToScale } from '../geo'; import { osmEntity, osmNode, osmNote, osmRelation, osmWay } from '../osm'; -import { utilArrayChunk, utilArrayGroupBy, utilArrayUniq, utilRebind, utilTiler, utilQsString } from '../util'; +import { utilArrayChunk, utilArrayGroupBy, utilArrayUniq, utilObjectOmit, utilRebind, utilTiler, utilQsString } from '../util'; var tiler = utilTiler(); var dispatch = d3_dispatch('apiStatusChange', 'authLoading', 'authDone', 'change', 'loading', 'loaded', 'loadedNotes'); + var urlroot = 'https://www.openstreetmap.org'; +var redirectPath = window.location.origin + window.location.pathname; var oauth = osmAuth({ url: urlroot, - oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT', - oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL', + client_id: '0tmNTmd0Jo1dQp4AUmMBLtGiD9YpMuXzHefitcuVStc', + client_secret: 'BTlNrNxIPitHdL4sP2clHw5KLoee9aKkA7dQbc0Bj7Q', + scope: 'read_prefs write_prefs write_api read_gpx write_notes', + redirect_uri: redirectPath + 'land.html', loading: authLoading, done: authDone }); + // hardcode default block of Google Maps var _imageryBlocklists = [/.*\.google(apis)?\..*\/(vt|kh)[\?\/].*([xyz]=.*){3}.*/]; var _tileCache = { toLoad: {}, loaded: {}, inflight: {}, seen: {}, rtree: new RBush() }; @@ -564,6 +568,11 @@ export default { }, + getUrlRoot: function() { + return urlroot; + }, + + changesetURL: function(changesetID) { return urlroot + '/changeset/' + changesetID; }, @@ -785,7 +794,7 @@ export default { var options = { method: 'PUT', path: '/api/0.6/changeset/create', - options: { header: { 'Content-Type': 'text/xml' } }, + headers: { 'Content-Type': 'text/xml' }, content: JXON.stringify(changeset.asJXON()) }; _changeset.inflight = oauth.xhr( @@ -806,7 +815,7 @@ export default { var options = { method: 'POST', path: '/api/0.6/changeset/' + changesetID + '/upload', - options: { header: { 'Content-Type': 'text/xml' } }, + headers: { 'Content-Type': 'text/xml' }, content: JXON.stringify(changeset.osmChangeJXON(changes)) }; _changeset.inflight = oauth.xhr( @@ -832,7 +841,7 @@ export default { oauth.xhr({ method: 'PUT', path: '/api/0.6/changeset/' + changeset.id + '/close', - options: { header: { 'Content-Type': 'text/xml' } } + headers: { 'Content-Type': 'text/xml' } }, function() { return true; }); } } @@ -1267,14 +1276,13 @@ export default { }, - switch: function(options) { - urlroot = options.urlroot; + switch: function(newOptions) { + urlroot = newOptions.url; - oauth.options(Object.assign({ - url: urlroot, - loading: authLoading, - done: authDone - }, options)); + // Copy the existing options, but omit 'access_token'. + // (if we did preauth, access_token won't work on a different server) + var oldOptions = utilObjectOmit(oauth.options(), 'access_token'); + oauth.options(Object.assign(oldOptions, newOptions)); this.reset(); this.userChangesets(function() {}); // eagerly load user details/changesets @@ -1384,7 +1392,7 @@ export default { that.userChangesets(function() {}); // eagerly load user details/changesets } - return oauth.authenticate(done); + oauth.authenticate(done); }, diff --git a/modules/ui/account.js b/modules/ui/account.js index 64b879dea..2d6203d70 100644 --- a/modules/ui/account.js +++ b/modules/ui/account.js @@ -1,76 +1,118 @@ import { t } from '../core/localizer'; import { svgIcon } from '../svg/icon'; + export function uiAccount(context) { - var osm = context.connection(); + const osm = context.connection(); - function update(selection) { - if (!osm) return; + function updateUserDetails(selection) { + if (!osm) return; - if (!osm.authenticated()) { - selection.selectAll('.userLink, .logoutLink') - .classed('hide', true); - return; - } + if (!osm.authenticated()) { // logged out + render(selection, null); + } else { + osm.userDetails((err, user) => render(selection, user)); + } + } - osm.userDetails(function(err, details) { - var userLink = selection.select('.userLink'), - logoutLink = selection.select('.logoutLink'); - userLink.html(''); - logoutLink.html(''); + function render(selection, user) { + let userInfo = selection.select('.userInfo'); + let loginLogout = selection.select('.loginLogout'); - if (err || !details) return; + if (user) { + userInfo + .html('') + .classed('hide', false); - selection.selectAll('.userLink, .logoutLink') - .classed('hide', false); + let userLink = userInfo + .append('a') + .attr('href', osm.userURL(user.display_name)) + .attr('target', '_blank'); - // Link - var userLinkA = userLink.append('a') - .attr('href', osm.userURL(details.display_name)) - .attr('target', '_blank'); + // Add user's image or placeholder + if (user.image_url) { + userLink.append('img') + .attr('class', 'icon pre-text user-icon') + .attr('src', user.image_url); + } else { + userLink + .call(svgIcon('#iD-icon-avatar', 'pre-text light')); + } - // Add thumbnail or dont - if (details.image_url) { - userLinkA.append('img') - .attr('class', 'icon pre-text user-icon') - .attr('src', details.image_url); - } else { - userLinkA - .call(svgIcon('#iD-icon-avatar', 'pre-text light')); - } + // Add user name + userLink.append('span') + .attr('class', 'label') + .html(user.display_name); - // Add user name - userLinkA.append('span') - .attr('class', 'label') - .text(details.display_name); + // show "Log Out" + loginLogout + .classed('hide', false) + .select('a') + .text(t('logout')) + .on('click', e => { + e.preventDefault(); + osm.logout(); + tryLogout(); + }); - logoutLink.append('a') - .attr('class', 'logout') - .attr('href', '#') - .call(t.append('logout')) - .on('click.logout', function(d3_event) { - d3_event.preventDefault(); - osm.logout(); - }); + } else { // no user + userInfo + .html('') + .classed('hide', true); + + // show "Log In" + loginLogout + .classed('hide', false) + .select('a') + .text(t('login')) + .on('click', e => { + e.preventDefault(); + osm.authenticate(); }); } + } - return function(selection) { + // OAuth2's idea of "logout" is just to get rid of the bearer token. + // If we try to "login" again, it will just grab the token again. + // What a user probably _really_ expects is to logout of OSM so that they can switch users. + function tryLogout() { + if (!osm) return; - selection.append('li') - .attr('class', 'userLink') - .classed('hide', true); + const url = osm.getUrlRoot() + '/logout?referer=%2Flogin'; + // Create a 600x550 popup window in the center of the screen + const w = 600; + const h = 550; + const settings = [ + ['width', w], + ['height', h], + ['left', window.screen.width / 2 - w / 2], + ['top', window.screen.height / 2 - h / 2], + ] + .map(x => x.join('=')) + .join(','); - selection.append('li') - .attr('class', 'logoutLink') - .classed('hide', true); + window.open(url, '_blank', settings); + } + + + return function(selection) { + if (!osm) return; + + selection.append('li') + .attr('class', 'userInfo') + .classed('hide', true); + + selection.append('li') + .attr('class', 'loginLogout') + .classed('hide', true) + .append('a') + .attr('href', '#'); + + osm.on('change.account', () => updateUserDetails(selection)); + updateUserDetails(selection); + }; - if (osm) { - osm.on('change.account', function() { update(selection); }); - update(selection); - } - }; } diff --git a/package.json b/package.json index 03d8e1de5..01d5f5072 100644 --- a/package.json +++ b/package.json @@ -58,8 +58,8 @@ "fast-json-stable-stringify": "2.1.0", "lodash-es": "~4.17.15", "marked": "~4.0.12", - "node-diff3": "3.1.0", - "osm-auth": "1.1.1", + "node-diff3": "~3.1.0", + "osm-auth": "~2.0.0", "pannellum": "2.5.6", "pbf": "^3.2.1", "polygon-clipping": "~0.15.1", @@ -122,4 +122,4 @@ "browserslist": [ "> 0.2%, last 6 major versions, Firefox ESR, maintained node versions" ] -} +} \ No newline at end of file diff --git a/test/spec/services/osm.js b/test/spec/services/osm.js index 8299f825e..bad227032 100644 --- a/test/spec/services/osm.js +++ b/test/spec/services/osm.js @@ -4,11 +4,10 @@ describe('iD.serviceOsm', function () { function login() { connection.switch({ - urlroot: 'http://www.openstreetmap.org', - oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT', - oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL', - oauth_token: 'foo', - oauth_token_secret: 'foo' + url: 'https://www.openstreetmap.org', + client_id: '0tmNTmd0Jo1dQp4AUmMBLtGiD9YpMuXzHefitcuVStc', + client_secret: 'BTlNrNxIPitHdL4sP2clHw5KLoee9aKkA7dQbc0Bj7Q', + access_token: 'foo' // preauth }); } @@ -28,7 +27,7 @@ describe('iD.serviceOsm', function () { serverXHR = sinon.fakeServer.create(); // authenticated calls use XHR via osm-auth context = iD.coreContext().assetPath('../dist/').init(); connection = context.connection(); - connection.switch({ urlroot: 'http://www.openstreetmap.org' }); + connection.switch({ url: 'https://www.openstreetmap.org' }); connection.reset(); spy = sinon.spy(); }); @@ -54,7 +53,7 @@ describe('iD.serviceOsm', function () { it('changes the connection id every time connection is switched', function () { var cid1 = connection.getConnectionId(); - connection.switch({ urlroot: 'https://api06.dev.openstreetmap.org' }); + connection.switch({ url: 'https://api06.dev.openstreetmap.org' }); var cid2 = connection.getConnectionId(); expect(cid2).to.be.above(cid1); }); @@ -62,11 +61,11 @@ describe('iD.serviceOsm', function () { describe('#changesetURL', function() { it('provides a changeset url', function() { - expect(connection.changesetURL(2)).to.eql('http://www.openstreetmap.org/changeset/2'); + expect(connection.changesetURL(2)).to.eql('https://www.openstreetmap.org/changeset/2'); }); it('allows secure connections', function() { - connection.switch({ urlroot: 'https://www.openstreetmap.org' }); + connection.switch({ url: 'https://www.openstreetmap.org' }); expect(connection.changesetURL(2)).to.eql('https://www.openstreetmap.org/changeset/2'); }); }); @@ -75,47 +74,47 @@ describe('iD.serviceOsm', function () { it('provides a local changesets url', function() { var center = [-74.65, 40.65]; var zoom = 17; - expect(connection.changesetsURL(center, zoom)).to.eql('http://www.openstreetmap.org/history#map=17/40.65000/-74.65000'); + expect(connection.changesetsURL(center, zoom)).to.eql('https://www.openstreetmap.org/history#map=17/40.65000/-74.65000'); }); }); describe('#entityURL', function() { it('provides an entity url for a node', function() { var e = iD.osmNode({id: 'n1'}); - expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/node/1'); + expect(connection.entityURL(e)).to.eql('https://www.openstreetmap.org/node/1'); }); it('provides an entity url for a way', function() { var e = iD.osmWay({id: 'w1'}); - expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/way/1'); + expect(connection.entityURL(e)).to.eql('https://www.openstreetmap.org/way/1'); }); it('provides an entity url for a relation', function() { var e = iD.osmRelation({id: 'r1'}); - expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/relation/1'); + expect(connection.entityURL(e)).to.eql('https://www.openstreetmap.org/relation/1'); }); }); describe('#historyURL', function() { it('provides a history url for a node', function() { var e = iD.osmNode({id: 'n1'}); - expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/node/1/history'); + expect(connection.historyURL(e)).to.eql('https://www.openstreetmap.org/node/1/history'); }); it('provides a history url for a way', function() { var e = iD.osmWay({id: 'w1'}); - expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/way/1/history'); + expect(connection.historyURL(e)).to.eql('https://www.openstreetmap.org/way/1/history'); }); it('provides a history url for a relation', function() { var e = iD.osmRelation({id: 'r1'}); - expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/relation/1/history'); + expect(connection.historyURL(e)).to.eql('https://www.openstreetmap.org/relation/1/history'); }); }); describe('#userURL', function() { it('provides a user url', function() { - expect(connection.userURL('bob')).to.eql('http://www.openstreetmap.org/user/bob'); + expect(connection.userURL('bob')).to.eql('https://www.openstreetmap.org/user/bob'); }); }); @@ -127,13 +126,13 @@ describe('iD.serviceOsm', function () { describe('#switch', function() { it('changes the URL', function() { - connection.switch({ urlroot: 'http://example.com' }); - expect(connection.changesetURL(1)).to.equal('http://example.com/changeset/1'); + connection.switch({ url: 'https://example.com' }); + expect(connection.changesetURL(1)).to.equal('https://example.com/changeset/1'); }); it('emits a change event', function() { connection.on('change', spy); - connection.switch({ urlroot: 'http://example.com' }); + connection.switch({ url: 'https://example.com' }); expect(spy).to.have.been.calledOnce; }); }); @@ -152,7 +151,7 @@ describe('iD.serviceOsm', function () { '}'; it('returns an object', function(done) { - fetchMock.mock('http://www.openstreetmap.org' + path, { + fetchMock.mock('https://www.openstreetmap.org' + path, { body: response, status: 200, headers: { 'Content-Type': 'application/json' } @@ -166,12 +165,12 @@ describe('iD.serviceOsm', function () { }); it('retries an authenticated call unauthenticated if 400 Bad Request', function (done) { - fetchMock.mock('http://www.openstreetmap.org' + path, { + fetchMock.mock('https://www.openstreetmap.org' + path, { body: response, status: 200, headers: { 'Content-Type': 'application/json' } }); - serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path, + serverXHR.respondWith('GET', 'https://www.openstreetmap.org' + path, [400, { 'Content-Type': 'text/plain' }, 'Bad Request']); login(); @@ -189,12 +188,12 @@ describe('iD.serviceOsm', function () { }); it('retries an authenticated call unauthenticated if 401 Unauthorized', function (done) { - fetchMock.mock('http://www.openstreetmap.org' + path, { + fetchMock.mock('https://www.openstreetmap.org' + path, { body: response, status: 200, headers: { 'Content-Type': 'application/json' } }); - serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path, + serverXHR.respondWith('GET', 'https://www.openstreetmap.org' + path, [401, { 'Content-Type': 'text/plain' }, 'Unauthorized']); login(); @@ -211,12 +210,12 @@ describe('iD.serviceOsm', function () { }); it('retries an authenticated call unauthenticated if 403 Forbidden', function (done) { - fetchMock.mock('http://www.openstreetmap.org' + path, { + fetchMock.mock('https://www.openstreetmap.org' + path, { body: response, status: 200, headers: { 'Content-Type': 'application/json' } }); - serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path, + serverXHR.respondWith('GET', 'https://www.openstreetmap.org' + path, [403, { 'Content-Type': 'text/plain' }, 'Forbidden']); login(); @@ -234,7 +233,7 @@ describe('iD.serviceOsm', function () { it('dispatches change event if 509 Bandwidth Limit Exceeded', function (done) { - fetchMock.mock('http://www.openstreetmap.org' + path, { + fetchMock.mock('https://www.openstreetmap.org' + path, { body: 'Bandwidth Limit Exceeded', status: 509, headers: { 'Content-Type': 'text/plain' } @@ -250,7 +249,7 @@ describe('iD.serviceOsm', function () { }); it('dispatches change event if 429 Too Many Requests', function (done) { - fetchMock.mock('http://www.openstreetmap.org' + path, { + fetchMock.mock('https://www.openstreetmap.org' + path, { body: '429 Too Many Requests', status: 429, headers: { 'Content-Type': 'text/plain' } @@ -347,7 +346,7 @@ describe('iD.serviceOsm', function () { '}'; it('loads a node', function(done) { - fetchMock.mock('http://www.openstreetmap.org/api/0.6/node/1.json', { + fetchMock.mock('https://www.openstreetmap.org/api/0.6/node/1.json', { body: nodeResponse, status: 200, headers: { 'Content-Type': 'application/json' } @@ -362,7 +361,7 @@ describe('iD.serviceOsm', function () { }); it('loads a way', function(done) { - fetchMock.mock('http://www.openstreetmap.org/api/0.6/way/1/full.json', { + fetchMock.mock('https://www.openstreetmap.org/api/0.6/way/1/full.json', { body: wayResponse, status: 200, headers: { 'Content-Type': 'application/json' } @@ -377,7 +376,7 @@ describe('iD.serviceOsm', function () { }); it('does not ignore repeat requests', function(done) { - fetchMock.mock('http://www.openstreetmap.org/api/0.6/node/1.json', { + fetchMock.mock('https://www.openstreetmap.org/api/0.6/node/1.json', { body: wayResponse, status: 200, headers: { 'Content-Type': 'application/json' } @@ -416,7 +415,7 @@ describe('iD.serviceOsm', function () { '}'; it('loads a node', function(done) { - fetchMock.mock('http://www.openstreetmap.org/api/0.6/node/1/1.json', { + fetchMock.mock('https://www.openstreetmap.org/api/0.6/node/1/1.json', { body: nodeResponse, status: 200, headers: { 'Content-Type': 'application/json' } @@ -431,7 +430,7 @@ describe('iD.serviceOsm', function () { }); it('loads a way', function(done) { - fetchMock.mock('http://www.openstreetmap.org/api/0.6/way/1/1.json', { + fetchMock.mock('https://www.openstreetmap.org/api/0.6/way/1/1.json', { body: wayResponse, status: 200, headers: { 'Content-Type': 'application/json' } @@ -446,7 +445,7 @@ describe('iD.serviceOsm', function () { }); it('does not ignore repeat requests', function(done) { - fetchMock.mock('http://www.openstreetmap.org/api/0.6/node/1/1.json', { + fetchMock.mock('https://www.openstreetmap.org/api/0.6/node/1/1.json', { body: nodeResponse, status: 200, headers: { 'Content-Type': 'application/json' } @@ -510,7 +509,7 @@ describe('iD.serviceOsm', function () { done(); }); - serverXHR.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/changesets?user=1', + serverXHR.respondWith('GET', 'https://www.openstreetmap.org/api/0.6/changesets?user=1', [200, { 'Content-Type': 'text/xml' }, changesetsXML]); serverXHR.respond(); }); @@ -539,7 +538,7 @@ describe('iD.serviceOsm', function () { done(); }); - serverXHR.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/changesets?user=1', + serverXHR.respondWith('GET', 'https://www.openstreetmap.org/api/0.6/changesets?user=1', [200, { 'Content-Type': 'text/xml' }, changesetsXML]); serverXHR.respond(); }); @@ -569,7 +568,7 @@ describe('iD.serviceOsm', function () { done(); }); - serverXHR.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/changesets?user=1', + serverXHR.respondWith('GET', 'https://www.openstreetmap.org/api/0.6/changesets?user=1', [200, { 'Content-Type': 'text/xml' }, changesetsXML]); serverXHR.respond(); }); @@ -768,7 +767,7 @@ describe('iD.serviceOsm', function () { describe('#status', function() { it('gets API status', function(done) { - fetchMock.mock('http://www.openstreetmap.org/api/capabilities', { + fetchMock.mock('https://www.openstreetmap.org/api/capabilities', { body: capabilitiesXML, status: 200, headers: { 'Content-Type': 'text/xml' } @@ -785,7 +784,7 @@ describe('iD.serviceOsm', function () { describe('#imageryBlocklists', function() { it('updates imagery blocklists', function(done) { - fetchMock.mock('http://www.openstreetmap.org/api/capabilities', { + fetchMock.mock('https://www.openstreetmap.org/api/capabilities', { body: capabilitiesXML, status: 200, headers: { 'Content-Type': 'text/xml' } @@ -802,4 +801,4 @@ describe('iD.serviceOsm', function () { }); }); -}); \ No newline at end of file +});