Date: Sat, 27 Mar 2021 15:21:51 +0100
Subject: [PATCH 06/12] hiding all metrics when client is dead
---
frontend/main.js | 4 ++--
frontend/style.css | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/frontend/main.js b/frontend/main.js
index ad3fb65..7b80010 100644
--- a/frontend/main.js
+++ b/frontend/main.js
@@ -711,11 +711,11 @@ function processUpdate(data, init) {
'' +
'' +
'' +
- '' +
+ '' +
'0.0 ' +
VELOCITY_UNIT.unit +
' | ' +
- '' +
+ '' +
'0.0 ' +
ALTITUDE_UNIT.unit +
'' +
diff --git a/frontend/style.css b/frontend/style.css
index 60628f7..b799543 100644
--- a/frontend/style.css
+++ b/frontend/style.css
@@ -324,7 +324,7 @@ a:last-child > .store-icon {
background-color: rgba(165,0,42,0.5);
}
-.marker p.dead > span.velocity {
+.marker p.dead > span.metric {
display: none;
}
From 9cbd1ccd1f2202383a936701434c23b7cb235ccf Mon Sep 17 00:00:00 2001
From: tuffnerdstuff
Date: Sat, 27 Mar 2021 16:48:50 +0100
Subject: [PATCH 07/12] Refactored LocationUpdatePackage
---
.../hauk/http/LocationUpdatePacket.java | 75 +++++++++++--------
1 file changed, 44 insertions(+), 31 deletions(-)
diff --git a/android/app/src/main/java/info/varden/hauk/http/LocationUpdatePacket.java b/android/app/src/main/java/info/varden/hauk/http/LocationUpdatePacket.java
index 8c80f50..21a86f7 100644
--- a/android/app/src/main/java/info/varden/hauk/http/LocationUpdatePacket.java
+++ b/android/app/src/main/java/info/varden/hauk/http/LocationUpdatePacket.java
@@ -5,9 +5,15 @@ import android.location.Location;
import android.util.Base64;
import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
import info.varden.hauk.Constants;
import info.varden.hauk.R;
@@ -48,39 +54,17 @@ public abstract class LocationUpdatePacket extends Packet {
super(ctx, session.getServerURL(), session.getConnectionParameters(), Constants.URL_PATH_POST_LOCATION);
setParameter(Constants.PACKET_PARAM_SESSION_ID, session.getID());
- // FIXME: Get rid of duplicate code
- if (session.getDerivableE2EKey() == null) {
- // If not using end-to-end encryption, send parameters in plain text.
- setParameter(Constants.PACKET_PARAM_LATITUDE, String.valueOf(location.getLatitude()));
- setParameter(Constants.PACKET_PARAM_LONGITUDE, String.valueOf(location.getLongitude()));
- setParameter(Constants.PACKET_PARAM_PROVIDER_ACCURACY, String.valueOf(accuracy.getMode()));
- setParameter(Constants.PACKET_PARAM_TIMESTAMP, String.valueOf(System.currentTimeMillis() / (double) TimeUtils.MILLIS_PER_SECOND));
+ Cipher cipher = initCipher(session);
- // Not all devices provide these parameters:
- if (location.hasSpeed()) setParameter(Constants.PACKET_PARAM_SPEED, String.valueOf(location.getSpeed()));
- if (location.hasAccuracy()) setParameter(Constants.PACKET_PARAM_ACCURACY, String.valueOf(location.getAccuracy()));
- if (location.hasAltitude()) setParameter(Constants.PACKET_PARAM_ALTITUDE, String.valueOf(location.getAltitude()));
- } else {
- // We're using end-to-end encryption - generate an IV and encrypt all parameters.
- try {
- Cipher cipher = Cipher.getInstance(Constants.E2E_TRANSFORMATION);
- cipher.init(Cipher.ENCRYPT_MODE, session.getDerivableE2EKey().deriveSpec(), new SecureRandom());
- byte[] iv = cipher.getIV();
- setParameter(Constants.PACKET_PARAM_INIT_VECTOR, Base64.encodeToString(iv, Base64.DEFAULT));
+ encryptAndSetParameter(Constants.PACKET_PARAM_LATITUDE, location.getLatitude(), cipher);
+ encryptAndSetParameter(Constants.PACKET_PARAM_LONGITUDE, location.getLongitude(), cipher);
+ encryptAndSetParameter(Constants.PACKET_PARAM_PROVIDER_ACCURACY, accuracy.getMode(), cipher);
+ encryptAndSetParameter(Constants.PACKET_PARAM_TIMESTAMP, System.currentTimeMillis() / (double) TimeUtils.MILLIS_PER_SECOND, cipher);
- setParameter(Constants.PACKET_PARAM_LATITUDE, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getLatitude()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
- setParameter(Constants.PACKET_PARAM_LONGITUDE, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getLongitude()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
- setParameter(Constants.PACKET_PARAM_PROVIDER_ACCURACY, Base64.encodeToString(cipher.doFinal(String.valueOf(accuracy.getMode()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
- setParameter(Constants.PACKET_PARAM_TIMESTAMP, Base64.encodeToString(cipher.doFinal(String.valueOf(System.currentTimeMillis() / (double) TimeUtils.MILLIS_PER_SECOND).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
-
- // Not all devices provide these parameters:
- if (location.hasSpeed()) setParameter(Constants.PACKET_PARAM_SPEED, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getSpeed()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
- if (location.hasAccuracy()) setParameter(Constants.PACKET_PARAM_ACCURACY, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getAccuracy()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
- if (location.hasAltitude()) setParameter(Constants.PACKET_PARAM_ALTITUDE, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getAltitude()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
- } catch (Exception e) {
- Log.e("Error was thrown when encrypting location data", e); //NON-NLS
- }
- }
+ // Not all devices provide these parameters:
+ if (location.hasSpeed()) encryptAndSetParameter(Constants.PACKET_PARAM_SPEED, location.getSpeed(), cipher);
+ if (location.hasAccuracy()) encryptAndSetParameter(Constants.PACKET_PARAM_ACCURACY, location.getAccuracy(), cipher);
+ if (location.hasAltitude()) encryptAndSetParameter(Constants.PACKET_PARAM_ALTITUDE, location.getAltitude(), cipher);
}
@SuppressWarnings("DesignForExtension")
@@ -116,4 +100,33 @@ public abstract class LocationUpdatePacket extends Packet {
throw new ServerException(err.toString());
}
}
+
+ private Cipher initCipher(Session session) {
+ Cipher cipher = null;
+ if (session.getDerivableE2EKey() != null) {
+ try {
+ cipher = Cipher.getInstance(Constants.E2E_TRANSFORMATION);
+ cipher.init(Cipher.ENCRYPT_MODE, session.getDerivableE2EKey().deriveSpec(), new SecureRandom());
+ byte[] iv = cipher.getIV();
+ setParameter(Constants.PACKET_PARAM_INIT_VECTOR, Base64.encodeToString(iv, Base64.DEFAULT));
+ } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException | NoSuchPaddingException exception) {
+ Log.e("Error was thrown while initializing E2E encryption", exception); //NON-NLS
+ }
+ }
+ return cipher;
+ }
+
+ private void encryptAndSetParameter(String key, V value, Cipher cipher) {
+ if (cipher != null) {
+ // We're using end-to-end encryption - generate an IV and encrypt all parameters.
+ try {
+ setParameter(key, Base64.encodeToString(cipher.doFinal(String.valueOf(value).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
+ } catch (BadPaddingException | IllegalBlockSizeException exception) {
+ Log.e("Error was thrown while encrypting location data", exception); //NON-NLS
+ }
+ } else {
+ // If not using end-to-end encryption, send parameters in plain text.
+ setParameter(key, String.valueOf(value));
+ }
+ }
}
From b5dad6ebe20f30deceae49d5d1dacb39841473e9 Mon Sep 17 00:00:00 2001
From: tuffnerdstuff
Date: Sat, 27 Mar 2021 17:41:33 +0100
Subject: [PATCH 08/12] Refactored post.php
---
backend-php/api/post.php | 51 ++++++++++++++++------------------------
1 file changed, 20 insertions(+), 31 deletions(-)
diff --git a/backend-php/api/post.php b/backend-php/api/post.php
index 63a7060..562e6e9 100644
--- a/backend-php/api/post.php
+++ b/backend-php/api/post.php
@@ -21,48 +21,37 @@ $sid = $_POST["sid"];
$session = new Client($memcache, $sid);
if (!$session->exists()) die($LANG['session_expired']."\n");
-// FIXME: Get rid of duplicate code
-if (!$session->isEncrypted()) {
- // Perform input validation.
- $lat = floatval($_POST["lat"]);
- $lon = floatval($_POST["lon"]);
- $time = floatval($_POST["time"]);
- if ($lat < -90 || $lat > 90 || $lon < -180 || $lon > 180) die($LANG['location_invalid']."\n");
+$lat = $_POST["lat"];
+$lon = $_POST["lon"];
+$time = $_POST["time"];
+$speed = isset($_POST["spd"]) ? $_POST["spd"] : null;
+$altitude = isset($_POST["alt"]) ? $_POST["alt"] : null;
+$accuracy = isset($_POST["acc"]) ? $_POST["acc"] : null;
+$provider = isset($_POST["prv"]) ? $_POST["prv"] : null;
- // Not all devices report speed and accuracy, but if available, report them
- // too.
- $speed = isset($_POST["spd"]) ? floatval($_POST["spd"]) : null;
- $altitude = isset($_POST["alt"]) ? doubleval($_POST["alt"]) : null;
- $accuracy = isset($_POST["acc"]) ? floatval($_POST["acc"]) : null;
- $provider = isset($_POST["prv"]) && $_POST["prv"] == "1" ? 1 : 0;
-
- // The location data object contains the sharing interval (i), duration (d)
- // and a location list (l). Each entry in the location list contains a
- // latitude, longitude, timestamp, provider, accuracy and speed, in that
- // order, as an array.
- $session->addPoint([$lat, $lon, $time, $provider, $accuracy, $speed, $altitude])->save();
-
-} else {
- // Input validation cannot be performed for end-to-end encrypted data.
- $lat = $_POST["lat"];
- $lon = $_POST["lon"];
- $time = $_POST["time"];
- $speed = isset($_POST["spd"]) ? $_POST["spd"] : null;
- $accuracy = isset($_POST["acc"]) ? $_POST["acc"] : null;
- $provider = isset($_POST["prv"]) ? $_POST["prv"] : null;
- $altitude = isset($_POST["alt"]) ? $_POST["alt"] : null;
+// The location data object contains the sharing interval (i), duration (d)
+// and a location list (l). Each entry in the location list contains a
+// latitude, longitude, timestamp, provider, accuracy and speed, in that
+// order, as an array.
+$point = [$lat, $lon, $time, $provider, $accuracy, $speed, $altitude];
+if ($session->isEncrypted()) {
// End-to-end encrypted connections also have an IV field used to decrypt
// the data fields.
requirePOST("iv");
$iv = $_POST["iv"];
// The IV field is prepended to the array to send to the client.
- $session->addPoint([$iv, $lat, $lon, $time, $provider, $accuracy, $speed, $altitude])->save();
+ array_unshift($point , $iv);
+} else {
+ // Perform input validation
+ if (floatval($lat) < -90 || floatval($lat) > 90 || floatval($lon) < -180 || floatval($lon) > 180) die($LANG['location_invalid']."\n");
}
+$session->addPoint($point)->save();
+
if ($session->hasExpired()) {
echo $LANG['session_expired']."\n";
} else {
echo "OK\n".getConfig("public_url")."?%s\n".implode(",", $session->getTargetIDs())."\n";
-}
+}
\ No newline at end of file
From 082da40d57a952f573a7f56bd721ee9986768c2a Mon Sep 17 00:00:00 2001
From: tuffnerdstuff
Date: Fri, 2 Apr 2021 00:40:20 +0200
Subject: [PATCH 09/12] Moved altitude to its own line and added labels
---
frontend/main.js | 15 ++++++++-------
frontend/style.css | 23 ++++++++++++++++++++---
2 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/frontend/main.js b/frontend/main.js
index 7b80010..cf8b08c 100644
--- a/frontend/main.js
+++ b/frontend/main.js
@@ -712,19 +712,20 @@ function processUpdate(data, init) {
'' +
'' +
'' +
- '0.0 ' +
- VELOCITY_UNIT.unit +
- ' | ' +
- '' +
- '0.0 ' +
- ALTITUDE_UNIT.unit +
+ 'vel:' +
+ '0.0 ' +
+ VELOCITY_UNIT.unit + '' +
+ '
' +
+ 'alt:' +
+ '0.0 ' +
+ ALTITUDE_UNIT.unit + '' +
'' +
'' +
'' +
'
' +
'',
// FIXME: hard-coded and dependend on style.css .marker
- iconAnchor: [60, 18]
+ iconAnchor: [48, 18]
});
shares[user].marker = L.marker([lat, lon], {icon: shares[user].icon}).on("click", function() {
follow(this.haukUser);
diff --git a/frontend/style.css b/frontend/style.css
index b799543..d7521b9 100644
--- a/frontend/style.css
+++ b/frontend/style.css
@@ -254,7 +254,7 @@ a:last-child > .store-icon {
/* The outer marker div. */
.marker {
- width: 120px;
+ width: 96px;
height: 62px;
}
@@ -302,8 +302,8 @@ a:last-child > .store-icon {
width: 100%;
border-radius: 15px;
text-align: center;
- padding: 2px 0;
- line-height: 100%;
+ padding: 5px 0 5px;
+ line-height: 125%;
font-family: sans-serif;
overflow: hidden;
white-space: nowrap;
@@ -333,3 +333,20 @@ a:last-child > .store-icon {
background: none;
border: none;
}
+
+.metric-label {
+ display:inline-block;
+ width: 30%;
+ text-align:right;
+ vertical-align: bottom;
+ padding-right: 0.5em;
+}
+
+.metric-value {
+ display:inline-block;
+ width: 70%;
+ text-align: left;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ vertical-align: bottom;
+}
From 27a19597a982c955eebfe3ee07fc719c8cb72c95 Mon Sep 17 00:00:00 2001
From: tuffnerdstuff
Date: Fri, 2 Apr 2021 12:04:34 +0200
Subject: [PATCH 10/12] Displaying metrics is optional
---
backend-php/dynamic.js.php | 2 ++
backend-php/include/config-sample.php | 6 ++++++
backend-php/include/inc.php | 2 ++
frontend/main.js | 4 +++-
4 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/backend-php/dynamic.js.php b/backend-php/dynamic.js.php
index 34a25e4..47e2867 100644
--- a/backend-php/dynamic.js.php
+++ b/backend-php/dynamic.js.php
@@ -16,5 +16,7 @@ var VELOCITY_DELTA_TIME =
var TRAIL_COLOR = ;
var VELOCITY_UNIT = ;
var ALTITUDE_UNIT = ;
+var SHOW_VELOCITY = ;
+var SHOW_ALTITUDE_AMSL = ;
var OFFLINE_TIMEOUT = ;
var REQUEST_TIMEOUT = ;
diff --git a/backend-php/include/config-sample.php b/backend-php/include/config-sample.php
index 466c398..9186369 100644
--- a/backend-php/include/config-sample.php
+++ b/backend-php/include/config-sample.php
@@ -278,6 +278,12 @@
// METERS, FEET
"altitude_unit" => METERS,
+// Display velocity below marker
+"show_velocity" => true,
+
+// Display altitude AMSL below marker
+"show_altitude_amsl"=> true,
+
// The publicly accessible URL to reach Hauk, with trailing slash.
"public_url" => 'https://example.com/'
diff --git a/backend-php/include/inc.php b/backend-php/include/inc.php
index f423828..9465ead 100644
--- a/backend-php/include/inc.php
+++ b/backend-php/include/inc.php
@@ -160,6 +160,8 @@ const DEFAULTS = array(
"trail_color" => '#d80037',
"velocity_unit" => KILOMETERS_PER_HOUR,
"altitude_unit" => METERS,
+ "show_velocity" => true,
+ "show_altitude_amsl" => true,
"public_url" => 'https://example.com/'
);
diff --git a/frontend/main.js b/frontend/main.js
index cf8b08c..394d33c 100644
--- a/frontend/main.js
+++ b/frontend/main.js
@@ -711,11 +711,13 @@ function processUpdate(data, init) {
'' +
'' +
'' +
- '' +
+ '' +
'vel:' +
'0.0 ' +
VELOCITY_UNIT.unit + '' +
'
' +
+ '' +
+ '' +
'alt:' +
'0.0 ' +
ALTITUDE_UNIT.unit + '' +
From 4ae423a407d20c82052aa05dfe39dec198063196 Mon Sep 17 00:00:00 2001
From: tuffnerdstuff
Date: Fri, 2 Apr 2021 12:34:19 +0200
Subject: [PATCH 11/12] Hiding altitude if value is null
---
frontend/main.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/frontend/main.js b/frontend/main.js
index 394d33c..8cc71fa 100644
--- a/frontend/main.js
+++ b/frontend/main.js
@@ -717,7 +717,7 @@ function processUpdate(data, init) {
VELOCITY_UNIT.unit + '' +
'
' +
'' +
- '' +
+ '' +
'alt:' +
'0.0 ' +
ALTITUDE_UNIT.unit + '' +
@@ -795,9 +795,13 @@ function processUpdate(data, init) {
// Altitude (If available)
var eAltitude = document.getElementById("altitude-" + shares[user].id);
var alt = 0;
+ var eAltitudeContainer = document.getElementById("altitude-container-" + shares[user].id);
if (lastPoint !== null && lastPoint.alt !== null && eAltitude !== null) {
alt = lastPoint.alt * ALTITUDE_UNIT.metersMultiplier;
eAltitude.textContent = alt.toFixed(1);
+ eAltitudeContainer.classList.remove("hidden");
+ } else {
+ eAltitudeContainer.classList.add("hidden");
}
// Flag that the first location has been received, for map centering.
From 33e19cb886e85532011232bde724b84660be4022 Mon Sep 17 00:00:00 2001
From: tuffnerdstuff
Date: Fri, 2 Apr 2021 13:19:46 +0200
Subject: [PATCH 12/12] Only unhide altitude if config allows it
---
frontend/main.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/frontend/main.js b/frontend/main.js
index 8cc71fa..e8ad30a 100644
--- a/frontend/main.js
+++ b/frontend/main.js
@@ -799,7 +799,9 @@ function processUpdate(data, init) {
if (lastPoint !== null && lastPoint.alt !== null && eAltitude !== null) {
alt = lastPoint.alt * ALTITUDE_UNIT.metersMultiplier;
eAltitude.textContent = alt.toFixed(1);
- eAltitudeContainer.classList.remove("hidden");
+ if (SHOW_ALTITUDE_AMSL) {
+ eAltitudeContainer.classList.remove("hidden");
+ }
} else {
eAltitudeContainer.classList.add("hidden");
}