Skip to content

Commit

Permalink
Make aggregate calls to the server using a native plugin
Browse files Browse the repository at this point in the history
The switch to WKWebView forced the use of CORS. There is no workaround.
https://ionicframework.com/docs/v3/wkwebview/#cors

We didn't encounter this in covid-19 repo since we made all calls through the
built-in native plugin that automatically adds the user token and sends out the
call.

In emission, though, we need make aggregate calls that should not have a user
token. We had been using XHR for this (through the angular `$http` server) and
all those calls broke.

While we could make the appropriate change on the server side, that would not
be consistent with our long term goal
(e-mission/e-mission-docs#408,
e-mission/e-mission-docs#288)

So for now, I use the alternative documented here
https://ionicframework.com/docs/v3/wkwebview/#i-cant-implement-cors

Concretely:
- add the native plugin
- add a new method `CommHelper.getAggregateData` that wraps it in a promise
- change all instances of `$http.post` -> `CommHelper.getAggregateData`
- use the configured connectUrl instead of hardcoding
- remove the hardcoded URL from index.html

Bonus fix:
- Dealt with error in the heatmap if there was no data and thus, no bounds by
  checking to see if the bounds were valid

Testing done:

Navigated through the app screens until all the aggregate calls were invoked
(see below). No errors in the console.

```
[Log] getting aggregate data without user authentication from http://localhost:8080/result/metrics/timestamp with arguments {"freq":"D","start_time":1586131200,"end_time":1587254400,"metric_list":["duration","median_speed","count","distance"],"is_return_aggregate":true} (cordova.js, line 1540)
[Log] getting aggregate data without user authentication from http://localhost:8080/result/heatmap/incidents/timestamp with arguments {"start_time":1587187062,"end_time":1587359861,"sel_region":null} (cordova.js, line 1540)
[Log] getting aggregate data without user authentication from http://localhost:8080/result/heatmap/pop.route/local_date with arguments {"modes":null,"from_local_date":{"year":2020,"month":4,"day":17,"hour":22},"to_local_date":{"year":2020,"month":4,"day":18,"hour":22},"sel_region":null} (cordova.js, line 1540)
[Log] getting aggregate data without user authentication from http://localhost:8080/result/heatmap/incidents/local_date with arguments {"modes":null,"from_local_date":{"year":2020,"month":4,"day":17,"hour":22},"to_local_date":{"year":2020,"month":4,"day":18,"hour":22},"sel_region":null} (cordova.js, line 1540)
```
  • Loading branch information
shankari committed Apr 20, 2020
1 parent 4bcd9ed commit 06177b9
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 20 deletions.
3 changes: 3 additions & 0 deletions config.cordovabuild.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@
<variable name="UPDATE_API" value="https://api.ionicjs.com" />
<variable name="MAX_STORE" value="2" />
</plugin>
<plugin name="cordova-plugin-advanced-http" spec="^2.4.1">
<variable name="OKHTTP_VERSION" value="3.10.0" />
</plugin>
<preference name="SplashShowOnlyFirstTime" value="false" />
<plugin name="edu.berkeley.eecs.emission.cordova.auth" spec="https://github.com/e-mission/cordova-jwt-auth.git#v1.6.2-alpha1" />
<plugin name="edu.berkeley.eecs.emission.cordova.comm" spec="https://github.com/e-mission/cordova-server-communication.git#v1.2.2" />
Expand Down
4 changes: 4 additions & 0 deletions package.cordovabuild.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
"UPDATE_API": "https://api.ionicjs.com",
"MAX_STORE": "2"
},
"cordova-plugin-advanced-http": {
"OKHTTP_VERSION": "3.10.0"
},
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
Expand All @@ -59,6 +62,7 @@
"dependencies": {
"cordova-android": "^8.1.0",
"cordova-ios": "^5.1.1",
"cordova-plugin-advanced-http": "^2.4.1",
"cordova-plugin-app-version": "~0.1.9",
"cordova-plugin-customurlscheme": "~4.3.0",
"cordova-plugin-device": "~2.0.1",
Expand Down
2 changes: 1 addition & 1 deletion www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com https://nominatim.openstreetmap.org https://e-mission.eecs.berkeley.edu emission: 'unsafe-eval'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: http://tile.stamen.com https://stamen-tiles.a.ssl.fastly.net https://stamen-tiles-*.a.ssl.fastly.net 'unsafe-inline'">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com https://nominatim.openstreetmap.org emission: 'unsafe-eval'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: http://tile.stamen.com https://stamen-tiles.a.ssl.fastly.net https://stamen-tiles-*.a.ssl.fastly.net 'unsafe-inline'">
<title></title>

<link href="lib/ionic/css/ionic.css" rel="stylesheet">
Expand Down
3 changes: 3 additions & 0 deletions www/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,21 @@ angular.module('emission', ['ionic',
throw "blank string instead of missing file on dynamically served app";
}
Logger.log("connectionConfigString = "+JSON.stringify(connectionConfig.data));
$rootScope.connectUrl = connectionConfig.data.connectUrl;
window.cordova.plugins.BEMConnectionSettings.setSettings(connectionConfig.data);
}).catch(function(err) {
// not displaying the error here since we have a backup
Logger.log("error "+JSON.stringify(err)+" while reading connection config, reverting to defaults");
window.cordova.plugins.BEMConnectionSettings.getDefaultSettings().then(function(defaultConfig) {
Logger.log("defaultConfig = "+JSON.stringify(defaultConfig));
$rootScope.connectUrl = defaultConfig.connectUrl;
window.cordova.plugins.BEMConnectionSettings.setSettings(defaultConfig);
}).catch(function(err) {
// displaying the error here since we don't have a backup
Logger.displayError("Error reading or setting connection defaults", err);
});
});
cordova.plugin.http.setDataSerializer('json');
});
console.log("Ending run");
})
Expand Down
7 changes: 5 additions & 2 deletions www/js/diary/current.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
'emission.plugin.logger'])

.controller('CurrMapCtrl', function($scope, Config, $state, $timeout, $ionicActionSheet,leafletData,
Logger, $window, PostTripManualMarker, CommHelper, $http, KVStore, $ionicPlatform, $translate) {
Logger, $window, PostTripManualMarker, CommHelper, KVStore, $ionicPlatform, $translate) {

console.log("controller CurrMapCtrl called from current.js");
var _map;
Expand Down Expand Up @@ -232,7 +232,9 @@

var getServerIncidents = function() {
Logger.log("Getting server incidents with call "+JSON.stringify(incidentServerCalldata));
$http.post("https://e-mission.eecs.berkeley.edu/result/heatmap/incidents/timestamp", incidentServerCalldata).then(function(res){
CommHelper.getAggregateData("result/heatmap/incidents/timestamp", incidentServerCalldata)
.then(function(res){
$scope.$apply(function() {
Logger.log("Server incidents result is "+JSON.stringify(res));
// Need to remove existing markers before adding new ones
// https://github.com/e-mission/e-mission-phone/pull/263#issuecomment-322669042
Expand All @@ -241,6 +243,7 @@
if(res.data.incidents.length > 0) {
addIncidents(res.data.incidents, _map, _serverIncidentMarkers);
}
});
}, function(error){
Logger.log("Error when getting incidents");
Logger.log(JSON.stringify(error));
Expand Down
23 changes: 15 additions & 8 deletions www/js/heatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ angular.module('emission.main.heatmap',['ui-leaflet', 'emission.services',
'emission.plugin.logger', 'emission.incident.posttrip.manual',
'ng-walkthrough', 'nzTour', 'emission.plugin.kvstore'])

.controller('HeatmapCtrl', function($scope, $ionicLoading, $ionicActionSheet, $http,
leafletData, Logger, Config, PostTripManualMarker,
.controller('HeatmapCtrl', function($scope, $ionicLoading, $ionicActionSheet,
leafletData, Logger, Config, PostTripManualMarker, CommHelper,
$window, nzTour, KVStore, $translate) {
$scope.mapCtrl = {};

Expand Down Expand Up @@ -44,11 +44,13 @@ angular.module('emission.main.heatmap',['ui-leaflet', 'emission.services',
sel_region: null
};
Logger.log("Sending data "+JSON.stringify(data));
return $http.post("https://e-mission.eecs.berkeley.edu/result/heatmap/pop.route/local_date", data)
return CommHelper.getAggregateData("result/heatmap/pop.route/local_date", data)
.then(function(response) {
if (angular.isDefined(response.data.lnglat)) {
Logger.log("Got points in heatmap "+response.data.lnglat.length);
$scope.showHeatmap(response.data.lnglat);
$scope.$apply(function() {
$scope.showHeatmap(response.data.lnglat);
});
} else {
Logger.log("did not find latlng in response data "+JSON.stringify(response.data));
}
Expand Down Expand Up @@ -240,7 +242,10 @@ angular.module('emission.main.heatmap',['ui-leaflet', 'emission.services',
// Don't set any layer - it will be filled in when the load completes
} else {
$ionicLoading.hide();
if (angular.isDefined(selData) && angular.isDefined(selData.layer)) {
if (angular.isDefined(selData) &&
angular.isDefined(selData.layer) &&
angular.isDefined(selData.bounds) &&
selData.bounds.isValid()) {
selData.layer.addTo(map);
map.fitBounds(selData.bounds);
$scope.selData = selData;
Expand Down Expand Up @@ -286,11 +291,13 @@ angular.module('emission.main.heatmap',['ui-leaflet', 'emission.services',
sel_region: null
};
Logger.log("Sending data "+JSON.stringify(data));
return $http.post("https://e-mission.eecs.berkeley.edu/result/heatmap/incidents/local_date", data)
return CommHelper.getAggregateData("result/heatmap/incidents/local_date", data)
.then(function(response) {
if (angular.isDefined(response.data.incidents)) {
Logger.log("Got incidents"+response.data.incidents.length);
$scope.showIncidents(response.data.incidents);
$scope.$apply(function() {
Logger.log("Got incidents"+response.data.incidents.length);
$scope.showIncidents(response.data.incidents);
});
} else {
Logger.log("did not find incidents in response data "+JSON.stringify(response.data));
}
Expand Down
15 changes: 7 additions & 8 deletions www/js/metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ angular.module('emission.main.metrics',['nvd3',
CommHelper, $window, $ionicPopup,
ionicDatePicker, $ionicPlatform,
FootprintHelper, CalorieCal, $ionicModal, $timeout, KVStore, CarbonDatasetHelper,
$rootScope, $location, $state, ReferHelper, $http, Logger,
$rootScope, $location, $state, ReferHelper, Logger,
$translate) {
var lastTwoWeeksQuery = true;
var first = true;
Expand Down Expand Up @@ -419,9 +419,8 @@ angular.module('emission.main.metrics',['nvd3',
delete clonedData.metric;
clonedData.metric_list = [DURATION, MEDIAN_SPEED, COUNT, DISTANCE];
clonedData.is_return_aggregate = true;
var getMetricsResult = $http.post(
"https://e-mission.eecs.berkeley.edu/result/metrics/timestamp",
clonedData)
var getMetricsResult = CommHelper.getAggregateData(
"result/metrics/timestamp", clonedData)
return getMetricsResult;
}

Expand Down Expand Up @@ -508,16 +507,16 @@ angular.module('emission.main.metrics',['nvd3',
$scope.uictrl.hasAggr = true;
if (angular.isDefined($scope.chartDataAggr)) { //Only have to check one because
// Restore the $apply if/when we go away from $http
// $scope.$apply(function() {
$scope.$apply(function() {
if (!$scope.uictrl.showMe) {
$scope.showCharts($scope.chartDataAggr);
}
// })
})
} else {
// $scope.$apply(function() {
$scope.$apply(function() {
$scope.showCharts([]);
console.log("did not find aggregate result in response data "+JSON.stringify(results[2]));
// });
});
}
})
.catch(function(error) {
Expand Down
22 changes: 21 additions & 1 deletion www/js/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
angular.module('emission.services', ['emission.plugin.logger',
'emission.plugin.kvstore'])

.service('CommHelper', function($http) {
.service('CommHelper', function($rootScope) {
var getConnectURL = function(successCallback, errorCallback) {
window.cordova.plugins.BEMConnectionSettings.getSettings(
function(settings) {
Expand Down Expand Up @@ -159,6 +159,26 @@ angular.module('emission.services', ['emission.plugin.logger',
window.cordova.plugins.BEMServerComm.getUserPersonalData("/pipeline/get_complete_ts", resolve, reject);
});
};

// host is automatically read from $rootScope.connectUrl, which is set in app.js
this.getAggregateData = function(path, data) {
return new Promise(function(resolve, reject) {
const full_url = $rootScope.connectUrl+"/"+path;
console.log("getting aggregate data without user authentication from "
+ full_url +" with arguments "+JSON.stringify(data));
const options = {
method: 'post',
data: data,
responseType: 'json'
}
cordova.plugin.http.sendRequest(full_url, options,
function(response) {
resolve(response);
}, function(error) {
reject(error);
});
});
};
})

.service('ReferHelper', function($http) {
Expand Down

0 comments on commit 06177b9

Please sign in to comment.