diff --git a/index.html b/index.html index dc2ef7144b..7d362532bb 100644 --- a/index.html +++ b/index.html @@ -47,13 +47,14 @@ .assetPath('dist/') .apiConnections([ { - 'urlroot': 'https://www.openstreetmap.org', - 'oauth_consumer_key': '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT', - 'oauth_secret': 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL' + url: 'https://www.openstreetmap.org', + client_id: window.location.hostname === '127.0.0.1' + ? 'oPbyNuXQIEh8ZI3zbjVWVmVyIaNB2guU6uLP2gQ3sfs' + : 'ZkRBVnOoBeMgwSajgG7E2bhgP5bR61knGYxsh9KKaHc', }, { - 'urlroot': 'https://api06.dev.openstreetmap.org', - 'oauth_consumer_key': 'zwQZFivccHkLs3a8Rq5CoS412fE5aPCXDw9DZj7R', - 'oauth_secret': 'aMnOOCwExO2XYtRVWJ1bI9QOdqh1cay2UgpbhA6p' + url: 'https://api06.dev.openstreetmap.org', + client_id: '4PEI2oq4LkV-3DsYLqVwfuONhww3HIUtRwRYT6JqbT8', + client_secret: 'Gjjv9jkw9mvoftQmNIu0X1YvN--6QWzTQdXjQtlS2Yw' } ]) .containerNode(container); diff --git a/modules/services/osm.js b/modules/services/osm.js index 5446c404ad..0affef7c1a 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -1,9 +1,9 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; import { json as d3_json, xml as d3_xml } from 'd3-fetch'; import { Extent, Projection, Tiler, geoZoomToScale, vecAdd } from '@id-sdk/math'; -import { utilArrayChunk, utilArrayGroupBy, utilArrayUniq, utilQsString, utilStringQs } from '@id-sdk/util'; +import { utilArrayChunk, utilArrayGroupBy, utilArrayUniq, utilObjectOmit, utilQsString, utilStringQs } from '@id-sdk/util'; import _throttle from 'lodash-es/throttle'; -import osmAuth from 'osm-auth'; +import { osmAuth } from 'osm-auth'; import RBush from 'rbush'; import { JXON } from '../util/jxon'; @@ -14,6 +14,7 @@ import { utilRebind } from '../util'; var tiler = new Tiler(); 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 q = utilStringQs(window.location.hash); var credentialsMode = 'omit'; if (q.hasOwnProperty('osm_api_url')) { @@ -22,8 +23,11 @@ if (q.hasOwnProperty('osm_api_url')) { } var oauth = osmAuth({ url: urlroot, - oauth_consumer_key: 'MlAcABGGdqadlgrjpmG6qSQu3bwbAgxC7hW0vRwm', - oauth_secret: 'M0g3lCJTvpnwMic0HYYwwTMpVvugNRlkycQL7so5', + client_id: window.location.hostname === '127.0.0.1' + ? 'oPbyNuXQIEh8ZI3zbjVWVmVyIaNB2guU6uLP2gQ3sfs' + : 'ZkRBVnOoBeMgwSajgG7E2bhgP5bR61knGYxsh9KKaHc', + scope: 'read_prefs write_prefs write_api read_gpx write_notes', + redirect_uri: redirectPath + 'land.html', loading: authLoading, done: authDone }); @@ -792,7 +796,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( @@ -813,7 +817,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( @@ -839,7 +843,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; }); } } @@ -1275,15 +1279,17 @@ export default { } }, + getUrlRoot: function() { + return urlroot; + }, - 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 @@ -1393,7 +1399,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 fbf9098e14..2d6203d700 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(); - - - function update(selection) { - if (!osm) return; - - if (!osm.authenticated()) { - selection.selectAll('.userLink, .logoutLink') - .classed('hide', true); - return; - } - - osm.userDetails(function(err, details) { - var userLink = selection.select('.userLink'), - logoutLink = selection.select('.logoutLink'); - - userLink.html(''); - logoutLink.html(''); - - if (err || !details) return; - - selection.selectAll('.userLink, .logoutLink') - .classed('hide', false); - - // Link - var userLinkA = userLink.append('a') - .attr('href', osm.userURL(details.display_name)) - .attr('target', '_blank'); - - // 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 - userLinkA.append('span') - .attr('class', 'label') - .html(details.display_name); - - logoutLink.append('a') - .attr('class', 'logout') - .attr('href', '#') - .html(t.html('logout')) - .on('click.logout', function(d3_event) { - d3_event.preventDefault(); - osm.logout(); - }); + const osm = context.connection(); + + + function updateUserDetails(selection) { + if (!osm) return; + + if (!osm.authenticated()) { // logged out + render(selection, null); + } else { + osm.userDetails((err, user) => render(selection, user)); + } + } + + + function render(selection, user) { + let userInfo = selection.select('.userInfo'); + let loginLogout = selection.select('.loginLogout'); + + if (user) { + userInfo + .html('') + .classed('hide', false); + + let userLink = userInfo + .append('a') + .attr('href', osm.userURL(user.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 user name + userLink.append('span') + .attr('class', 'label') + .html(user.display_name); + + // show "Log Out" + loginLogout + .classed('hide', false) + .select('a') + .text(t('logout')) + .on('click', e => { + e.preventDefault(); + osm.logout(); + tryLogout(); + }); + + } 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(); }); } + } + + + // 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; + + 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(','); + + window.open(url, '_blank', settings); + } + + return function(selection) { + if (!osm) return; - return function(selection) { + selection.append('li') + .attr('class', 'userInfo') + .classed('hide', true); - selection.append('li') - .attr('class', 'userLink') - .classed('hide', true); + selection.append('li') + .attr('class', 'loginLogout') + .classed('hide', true) + .append('a') + .attr('href', '#'); - selection.append('li') - .attr('class', 'logoutLink') - .classed('hide', true); + 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 0b71f719e8..33240055a4 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "lodash-es": "~4.17.15", "marked": "~3.0.8", "node-diff3": "~3.1.0", - "osm-auth": "1.1.1", + "osm-auth": "^2.5.0", "pannellum": "2.5.6", "pbf": "^3.2.1", "polygon-clipping": "~0.15.1", @@ -130,4 +130,4 @@ "browserslist": [ "> 0.2%, last 6 major versions, Firefox ESR, IE 11, maintained node versions" ] -} \ No newline at end of file +}