diff --git a/aserve.js b/aserve.js
new file mode 100644
index 0000000..dba992d
--- /dev/null
+++ b/aserve.js
@@ -0,0 +1,100 @@
+const express = require('express');
+const { createHash } = require('crypto');
+
+
+const app = express();
+const port = 8356;
+const geonJsonTemplate = {
+ type: "FeatureCollection",
+ features: [],
+ "marker-symbol-images": {
+ "star": "data:image/svg+xml;utf8,",
+ "star-stroked": "data:image/svg+xml;utf8,"
+ }
+};
+
+app.all('/locations.geojson', (req, res) => {
+ // Verify Inputs
+ 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').replaceAll('\n', '');
+ hazeUser = paramAuth.split(":")[0];
+ hazePwHash = paramAuth.split(":")[1];
+ }
+ const haze = new WebSocket('wss://do.ecven.com:8120/explr');
+ haze.addEventListener('message', (event) => {
+ const data = JSON.parse(event.data);
+ let haze_authToken = '', haze_username = '';
+ switch (data['event']) {
+ case "connected":
+ let pld = {
+ "event": "authenticateAccount_request",
+ "body": [
+ {
+ "password": hazePwHash,
+ "email": hazeUser
+ }
+ ],
+ "socketMessageId": 0
+ };
+ haze.send(JSON.stringify(pld));
+ break;
+ case "authenticateAccount_response":
+ if (data['body']['response'] === 1) {
+ haze_authToken = data['body']['authToken'];
+ 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 });
+ haze.close();
+ res.end();
+ }
+ break;
+ case "getMyLocationsRequest_response":
+ if (data['body']['response'] === 1) {
+ const hazeLocations = data['body']['locations'].map(location => {
+ return {
+ type: "Feature",
+ geometry: {
+ type: "Point",
+ coordinates: [location['coordinates']['longitude'], location['coordinates']['latitude']]
+ },
+ properties: {
+ id: location['id'],
+ title: location['name'],
+ "marker-symbol": location['isUnconfirmedLocation'] === 1 ? "star-stroked" : "star",
+ }
+ }
+ });
+ res.setHeader('Content-Type', 'application/json');
+ haze.close();
+ res.end(JSON.stringify({
+ ...geonJsonTemplate,
+ features: hazeLocations
+ }));
+ } else {
+ console.dir(data);
+ res.status(500).send('Failed to retrieve locations');
+ haze.close();
+ res.end();
+ }
+ break;
+ default:
+ console.dir(data);
+ res.status(500).send('Unexpected response from Haze API');
+ haze.close();
+ res.end();
+ }
+ });
+});
+
+app.listen(port, () => {
+ console.log(`Server is running on http://localhost:${port}`);
+});
diff --git a/dehaze.service b/dehaze.service
new file mode 100644
index 0000000..a7849fc
--- /dev/null
+++ b/dehaze.service
@@ -0,0 +1,10 @@
+[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
new file mode 100755
index 0000000..ca6ac36
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,4 @@
+#!/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 ed34899..94c5ee2 100644
--- a/serve.js
+++ b/serve.js
@@ -1,12 +1,10 @@
-const { loadEnvFile } = require('node:process');
const express = require('express');
const auth = require('express-basic-auth');
const { createHash } = require('crypto');
-loadEnvFile();
const app = express();
-const port = process.env.PORT || 3000;
+const port = 8355;
const geonJsonTemplate = {
type: "FeatureCollection",
features: [],
@@ -15,7 +13,6 @@ const geonJsonTemplate = {
"star-stroked": "data:image/svg+xml;utf8,"
}
};
-
app.use(auth({
authorizer: (username, password) => {
return true;
@@ -24,17 +21,25 @@ app.use(auth({
app.all('/locations.geojson', (req, res) => {
// Verify Inputs
- if (!req.auth.user || !req.auth.password) {
+ 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');
+ 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) => {
const data = JSON.parse(event.data);
@@ -46,7 +51,7 @@ app.all('/locations.geojson', (req, res) => {
"body": [
{
"password": hazePwHash,
- "email": req.auth.user
+ "email": hazeUser
}
],
"socketMessageId": 0
@@ -56,7 +61,6 @@ app.all('/locations.geojson', (req, res) => {
if (data['body']['response'] === 1) {
haze_authToken = data['body']['authToken'];
haze_username = data['body']['username'];
- console.dir(data);
haze.send('{"event": "getMyLocationsRequest_request","body": [{"higlightImages": true}],"socketMessageId": 0}');
} else {
res.status(401).json({ ...data, password: req.auth.password });