diff --git a/src/main/java/alfio/config/MvcConfiguration.java b/src/main/java/alfio/config/MvcConfiguration.java index cafb633260..080edf10d9 100644 --- a/src/main/java/alfio/config/MvcConfiguration.java +++ b/src/main/java/alfio/config/MvcConfiguration.java @@ -230,7 +230,7 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response, + " frame-src 'self' https://js.stripe.com https://www.google.com;" + " font-src 'self';"// + " media-src blob: 'self';"//for loading camera api - + " connect-src 'self' https://api.stripe.com https://maps.googleapis.com/;" //<- currently stripe.js use jsonp but if they switch to xmlhttprequest+cors we will be ready + + " connect-src 'self' https://api.stripe.com https://maps.googleapis.com/ https://geocoder.cit.api.here.com;" //<- currently stripe.js use jsonp but if they switch to xmlhttprequest+cors we will be ready + (environment.acceptsProfiles(Initializer.PROFILE_DEBUG_CSP) ? " report-uri /report-csp-violation" : "")); } }; diff --git a/src/main/java/alfio/controller/api/admin/LocationApiController.java b/src/main/java/alfio/controller/api/admin/LocationApiController.java index dff82a4cd9..c9c48c001d 100644 --- a/src/main/java/alfio/controller/api/admin/LocationApiController.java +++ b/src/main/java/alfio/controller/api/admin/LocationApiController.java @@ -21,6 +21,8 @@ import alfio.model.system.Configuration; import alfio.model.system.ConfigurationKeys; import com.moodysalem.TimezoneMapper; +import lombok.AllArgsConstructor; +import lombok.Getter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @@ -46,40 +48,73 @@ public String unhandledException(Exception e) { return e.getMessage(); } - @RequestMapping(value = "/location/maps-client-api-key") - public String mapsClientApiKey() { - return configurationManager.getStringConfigValue(Configuration.getSystemConfiguration(ConfigurationKeys.MAPS_CLIENT_API_KEY)).orElse(null); - } - - @RequestMapping(value = "/location/timezones") + @RequestMapping("/location/timezones") public List getTimezones() { List s = new ArrayList<>(ZoneId.getAvailableZoneIds()); s.sort(String::compareTo); return s; } - @RequestMapping(value = "/location/timezone") + @RequestMapping("/location/timezone") public String getTimezone(@RequestParam("lat") double lat, @RequestParam("lng") double lng) { String tzId = TimezoneMapper.tzNameAt(lat, lng); return getTimezones().contains(tzId) ? tzId : null; } - @RequestMapping(value = "/location/static-map-image") + + + @RequestMapping("/location/static-map-image") public String getMapImage( @RequestParam("lat") String lat, @RequestParam("lng") String lng, - @RequestParam("orgId") int orgId, + @RequestParam(value = "orgId", required = false) Integer orgId, @RequestParam(value = "eventId", required = false) Integer eventId) { - Function pathKeyBuilder = (key) -> - eventId == null ? Configuration.from(orgId, key) : Configuration.from(orgId, eventId, key); + Function pathKeyBuilder = (key) -> { + if(orgId == null && eventId == null) { + return Configuration.getSystemConfiguration(key); + } else if (eventId == null) { + return Configuration.from(orgId, key); + } else { + return Configuration.from(orgId, eventId, key); + } + }; - Map> geoInfoConfiguration = configurationManager.getStringConfigValueFrom( - pathKeyBuilder.apply(ConfigurationKeys.MAPS_PROVIDER), - pathKeyBuilder.apply(ConfigurationKeys.MAPS_CLIENT_API_KEY), - pathKeyBuilder.apply(ConfigurationKeys.MAPS_HERE_APP_ID), - pathKeyBuilder.apply(ConfigurationKeys.MAPS_HERE_APP_CODE)); + Map> geoInfoConfiguration = getGeoConf(pathKeyBuilder); return LocationDescriptor.getMapUrl(lat, lng, geoInfoConfiguration); } + + private Map> getGeoConf(Function pathKeyBuilder) { + return configurationManager.getStringConfigValueFrom( + pathKeyBuilder.apply(ConfigurationKeys.MAPS_PROVIDER), + pathKeyBuilder.apply(ConfigurationKeys.MAPS_CLIENT_API_KEY), + pathKeyBuilder.apply(ConfigurationKeys.MAPS_HERE_APP_ID), + pathKeyBuilder.apply(ConfigurationKeys.MAPS_HERE_APP_CODE)); + } + + @RequestMapping("/location/map-provider-client-api-key") + public ProviderAndKeys getGeoInfoProviderAndKeys() { + + Function pathKeyBuilder = (key) -> Configuration.getSystemConfiguration(key); + + Map> geoInfoConfiguration = getGeoConf(pathKeyBuilder); + + ConfigurationKeys.GeoInfoProvider provider = LocationDescriptor.getProvider(geoInfoConfiguration); + + Map apiKeys = new HashMap<>(); + + geoInfoConfiguration.forEach((k,v) -> { + v.ifPresent(value -> apiKeys.put(k, value)); + }); + + return new ProviderAndKeys(provider, apiKeys); + } + + @AllArgsConstructor + @Getter + public static class ProviderAndKeys { + private final ConfigurationKeys.GeoInfoProvider provider; + private Map keys; + } } diff --git a/src/main/java/alfio/model/modification/support/LocationDescriptor.java b/src/main/java/alfio/model/modification/support/LocationDescriptor.java index 4c344b9eac..0f8e402a29 100644 --- a/src/main/java/alfio/model/modification/support/LocationDescriptor.java +++ b/src/main/java/alfio/model/modification/support/LocationDescriptor.java @@ -74,7 +74,7 @@ public static String getMapUrl(String lat, String lng, Map> geoConf) { + public static ConfigurationKeys.GeoInfoProvider getProvider(Map> geoConf) { if((!geoConf.containsKey(ConfigurationKeys.MAPS_PROVIDER) || !geoConf.get(ConfigurationKeys.MAPS_PROVIDER).isPresent()) && (geoConf.containsKey(ConfigurationKeys.MAPS_CLIENT_API_KEY) && geoConf.get(ConfigurationKeys.MAPS_CLIENT_API_KEY).isPresent())) { return ConfigurationKeys.GeoInfoProvider.GOOGLE; diff --git a/src/main/webapp/resources/js/admin/service/service.js b/src/main/webapp/resources/js/admin/service/service.js index 47781d2f3c..274fa55a26 100644 --- a/src/main/webapp/resources/js/admin/service/service.js +++ b/src/main/webapp/resources/js/admin/service/service.js @@ -334,16 +334,96 @@ baseServices.service("LocationService", function($http, $q, HttpErrorHandler) { - function mapUrl(lat, lng, key) { + var reqCounter = 0; + + function getMapUrl(latitude, longitude, orgId, eventId) { + return $http.get('/admin/api/location/static-map-image', {params: {lat: latitude, lng: longitude, orgId : orgId, eventId: eventId}}).then(function(res) { + return res.data; + }); + } + + + function handleGoogleGeolocate(location, locService, apiKeyAndProvider, resolve, reject) { + var key = apiKeyAndProvider.keys['MAPS_CLIENT_API_KEY']; + var keyParam = key ? ('&key='+encodeURIComponent(key)) : ''; - return "https://maps.googleapis.com/maps/api/staticmap?center="+lat+","+lng+"&zoom=16&size=400x400&markers=color:blue%7Clabel:E%7C"+lat+","+lng+""+keyParam; + + if(!window.google || !window.google.maps) { + + reqCounter++; + + var script = document.createElement('script'); + + var callBackName = 'clientGeolocate'+reqCounter; + + script.src = 'https://maps.googleapis.com/maps/api/js?libraries=places&callback='+callBackName+keyParam; + document.head.appendChild(script); + window[callBackName] = function() { + search(); + } + } else { + search(); + } + + function search() { + var geocoder = new window.google.maps.Geocoder(); + geocoder.geocode({'address': location}, function(results, status) { + if (status === 'OK') { + var ret = {}; + ret.latitude = ""+results[0].geometry.location.lat() + ret.longitude = ""+results[0].geometry.location.lng() + $q.all([getMapUrl(ret.latitude, ret.longitude), locService.getTimezone(ret.latitude, ret.longitude)]).then(function(success) { + ret.mapUrl = success[0]; + var tz = success[1]; + if(tz.data) { + ret.timeZone = tz.data; + } + resolve(ret); + }, function () { + reject(); + }) + + } else { + reject(); + } + }); + } } - var reqCounter = 0; + + function handleHEREGeolocate(location, locService, apiKeyAndProvider, resolve, reject) { + var appId = apiKeyAndProvider.keys['MAPS_HERE_APP_ID']; + var appCode = apiKeyAndProvider.keys['MAPS_HERE_APP_CODE']; + $http.get('https://geocoder.cit.api.here.com/6.2/geocode.json', {params: {app_id: appId, app_code: appCode, searchtext: location}}).then(function(res) { + var view = res.data.Response.View; + if(view.length > 0 && view[0].Result.length > 0 && view[0].Result[0].Location) { + var location = view[0].Result[0].Location; + var pos = location.DisplayPosition; + var ret = {latitude: pos.Latitude, longitude: pos.Longitude}; + console.log(view); + + $q.all([getMapUrl(ret.latitude, ret.longitude), locService.getTimezone(ret.latitude, ret.longitude)]).then(function(success) { + ret.mapUrl = success[0]; + var tz = success[1]; + if(tz.data) { + ret.timeZone = tz.data; + } + resolve(ret); + }, function () { + reject(); + }) + } else { + reject(); + } + + }, function () { + reject(); + }) + } return { mapApiKey: function() { - return $http.get('/admin/api/location/maps-client-api-key.json').then(function(res) { + return $http.get('/admin/api/location/map-provider-client-api-key').then(function(res) { return res.data; }); }, @@ -351,44 +431,14 @@ var locService = this; return $q(function(resolve, reject) { - locService.mapApiKey().then(function(key) { - var keyParam = key ? ('&key='+encodeURIComponent(key)) : ''; - - if(!window.google || !window.google.maps) { - - reqCounter++; - - var script = document.createElement('script'); + locService.mapApiKey().then(function(apiKeyAndProvider) { - var callBackName = 'clientGeolocate'+reqCounter; - - script.src = 'https://maps.googleapis.com/maps/api/js?libraries=places&callback='+callBackName+keyParam; - document.head.appendChild(script); - window[callBackName] = function() { - search(); - } + if(apiKeyAndProvider.provider === 'GOOGLE') { + handleGoogleGeolocate(location, locService, apiKeyAndProvider, resolve, reject); + } else if (apiKeyAndProvider.provider === 'HERE') { + handleHEREGeolocate(location, locService, apiKeyAndProvider, resolve, reject); } else { - search(); - } - - function search() { - var geocoder = new window.google.maps.Geocoder(); - geocoder.geocode({'address': location}, function(results, status) { - if (status === 'OK') { - var ret = {}; - ret.latitude = ""+results[0].geometry.location.lat() - ret.longitude = ""+results[0].geometry.location.lng() - ret.mapUrl = mapUrl(ret.latitude, ret.longitude, key); - locService.getTimezone(ret.latitude, ret.longitude).then(function(res) { - if(res.data) { - ret.timeZone = res.data; - } - resolve(ret); - }); - } else { - reject(); - } - }); + alert('Must provide an API key (google or HERE maps)') } }) @@ -400,11 +450,7 @@ getTimezones: function() { return $http.get('/admin/api/location/timezones'); }, - getMapUrl : function(latitude, longitude, orgId, eventId) { - return $http.get('/admin/api/location/static-map-image', {params: {lat: latitude, lng: longitude, orgId : orgId, eventId: eventId}}).then(function(res) { - return res.data; - }); - } + getMapUrl : getMapUrl }; });