diff --git a/README.md b/README.md
index d4cdfc0..eb20df1 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,27 @@
# DeHaze
Port the Haze Explr API to GEOJSON for use in GIS applications.
+
+This was a quick and dirty project, and will probably get some updates slowly in the future. I put what I learned from this in the [HacDC Wiki](https://wiki.hacdc.org/en/Projects/API/HazeExplr).
+
+## Usage
+
+```bash
+npm i
+node serve.js
+```
+
+To use the endpoint, replace 'EMAIL' and 'PASSWORD' with your Haze Explr account details:
+
+```bash
+echo "EMAIL:`echo 'PASSWORD' | sha256sum | sed -e 's/ -//'`" | base64
+```
+
+Then, make a request to the endpoint with the resulting string as the value of the `auth` query parameter:
+
+```bash
+curl "http://localhost:3000/locations?auth=BASE64_ENCODED_STRING"
+```
+
+
+`basicauth_serve.js` does the same thing bus expects account details to be passed via basic HTTP auth, but does not work with QGIS.
diff --git a/aserve.js b/basicauth_serve.js
similarity index 87%
rename from aserve.js
rename to basicauth_serve.js
index dba992d..b1b63bc 100644
--- a/aserve.js
+++ b/basicauth_serve.js
@@ -1,9 +1,10 @@
const express = require('express');
+const auth = require('express-basic-auth');
const { createHash } = require('crypto');
const app = express();
-const port = 8356;
+const port = 8355;
const geonJsonTemplate = {
type: "FeatureCollection",
features: [],
@@ -12,20 +13,32 @@ const geonJsonTemplate = {
"star-stroked": "data:image/svg+xml;utf8,"
}
};
+app.use(auth({
+ authorizer: (username, password) => {
+ return true;
+ }
+}));
app.all('/locations.geojson', (req, res) => {
// Verify Inputs
- if (!req.query.auth) {
+ if ((!req.auth.user || !req.auth.password) && (!req.query.auth)) {
res.status(401).send('Unauthorized');
return;
}
// Query Haze API Websocket
let hazePwHash = null;
let hazeUser = null;
- if (req.query.auth){
- let paramAuth = Buffer.from(req.query.auth, 'base64').toString('utf-8').replaceAll('\n', '');
- hazeUser = paramAuth.split(":")[0];
+ if (req.query.auth) {
+ let paramAuth = Buffer.from(req.query.auth, 'base64').toString('utf-8');
+ hawUser = paramAuth.split(":")[0];
hazePwHash = paramAuth.split(":")[1];
+ } else {
+ hazeUser = req.auth.user;
+ if (/\b[A-Fa-f0-9]{64}\b/.test(req.auth.password)) {
+ hazePwHash = req.auth.password;
+ } else {
+ hazePwHash = createHash('sha256').update(req.auth.password).digest('hex');
+ }
}
const haze = new WebSocket('wss://do.ecven.com:8120/explr');
haze.addEventListener('message', (event) => {
@@ -33,7 +46,7 @@ app.all('/locations.geojson', (req, res) => {
let haze_authToken = '', haze_username = '';
switch (data['event']) {
case "connected":
- let pld = {
+ haze.send(JSON.stringify({
"event": "authenticateAccount_request",
"body": [
{
@@ -42,8 +55,7 @@ app.all('/locations.geojson', (req, res) => {
}
],
"socketMessageId": 0
- };
- haze.send(JSON.stringify(pld));
+ }));
break;
case "authenticateAccount_response":
if (data['body']['response'] === 1) {
@@ -51,8 +63,8 @@ app.all('/locations.geojson', (req, res) => {
haze_username = data['body']['username'];
haze.send('{"event": "getMyLocationsRequest_request","body": [{"higlightImages": true}],"socketMessageId": 0}');
} else {
- console.dir(req.query);
- res.status(401).json({ ...data, password: req.query.auth });
+ console.dir(req.query);
+ res.status(401).json({ ...data, password: req.auth.password });
haze.close();
res.end();
}
diff --git a/dehaze.service b/dehaze.service
deleted file mode 100644
index a7849fc..0000000
--- a/dehaze.service
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Descripton=HazeExplr API porting tool
-
-[Service]
-ExecStart=/home/liz/dehaze/run.sh
-User=liz
-
-[Install]
-WantedBy=multi-user.target
-
diff --git a/run.sh b/run.sh
deleted file mode 100755
index ca6ac36..0000000
--- a/run.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-cd /home/liz/dehaze
-/home/liz/.nvm/versions/node/v24.14.1/bin/node aserve.js &
-/home/liz/.nvm/versions/node/v24.14.1/bin/node serve.js
diff --git a/serve.js b/serve.js
index 94c5ee2..279b8f8 100644
--- a/serve.js
+++ b/serve.js
@@ -1,10 +1,8 @@
const express = require('express');
-const auth = require('express-basic-auth');
const { createHash } = require('crypto');
-
const app = express();
-const port = 8355;
+const port = 8356;
const geonJsonTemplate = {
type: "FeatureCollection",
features: [],
@@ -13,32 +11,20 @@ const geonJsonTemplate = {
"star-stroked": "data:image/svg+xml;utf8,"
}
};
-app.use(auth({
- authorizer: (username, password) => {
- return true;
- }
-}));
app.all('/locations.geojson', (req, res) => {
// Verify Inputs
- if ((!req.auth.user || !req.auth.password) && (!req.query.auth)) {
+ if (!req.query.auth) {
res.status(401).send('Unauthorized');
return;
}
// Query Haze API Websocket
let hazePwHash = null;
let hazeUser = null;
- if (req.query.auth){
- let paramAuth = Buffer.from(req.query.auth, 'base64').toString('utf-8');
- hawUser = paramAuth.split(":")[0];
+ if (req.query.auth) {
+ let paramAuth = Buffer.from(req.query.auth, 'base64').toString('utf-8').replaceAll('\n', '');
+ hazeUser = paramAuth.split(":")[0];
hazePwHash = paramAuth.split(":")[1];
- } else {
- hazeUser = req.auth.user;
- if (/\b[A-Fa-f0-9]{64}\b/.test(req.auth.password)) {
- hazePwHash = req.auth.password;
- } else {
- hazePwHash = createHash('sha256').update(req.auth.password).digest('hex');
- }
}
const haze = new WebSocket('wss://do.ecven.com:8120/explr');
haze.addEventListener('message', (event) => {
@@ -46,7 +32,7 @@ app.all('/locations.geojson', (req, res) => {
let haze_authToken = '', haze_username = '';
switch (data['event']) {
case "connected":
- haze.send(JSON.stringify({
+ let pld = {
"event": "authenticateAccount_request",
"body": [
{
@@ -55,7 +41,8 @@ app.all('/locations.geojson', (req, res) => {
}
],
"socketMessageId": 0
- }));
+ };
+ haze.send(JSON.stringify(pld));
break;
case "authenticateAccount_response":
if (data['body']['response'] === 1) {
@@ -63,7 +50,8 @@ app.all('/locations.geojson', (req, res) => {
haze_username = data['body']['username'];
haze.send('{"event": "getMyLocationsRequest_request","body": [{"higlightImages": true}],"socketMessageId": 0}');
} else {
- res.status(401).json({ ...data, password: req.auth.password });
+ console.dir(req.query);
+ res.status(401).json({ ...data, password: req.query.auth });
haze.close();
res.end();
}