Compare commits

...
5 Commits
Author SHA1 Message Date
Elizabeth Cray 026bd0f7a1 Fixed device reporting 2026-08-02 14:15:56 -04:00
Elizabeth Cray def1070589 Add device reporting 2026-08-02 14:01:59 -04:00
Elizabeth Cray 3988db9bde Fix missing define 2026-07-27 07:34:55 -04:00
Elizabeth Cray 07b66a7323 Add todo 2026-07-26 22:41:11 -04:00
Elizabeth Cray 350c22887d Fixed updated auth handling 2026-07-26 22:40:07 -04:00
2 changed files with 102 additions and 46 deletions
+7 -2
View File
@@ -24,17 +24,19 @@ app.all(/.*/, (req, res) => {
let hazePwHash = null;
let hazeUser = null;
if (req.query.auth) {
request({
let api_data = {
...reqOpts,
url: reqOpts.url + req.baseUrl,
headers: {
Authorization: `Basic ${req.query.auth}`
}
}, (error, response, body) => {
};
request(api_data, (error, response, body) => {
if (error) {
res.status(500).send('Internal Server Error');
return;
} else if (response.statusCode !== 200) {
console.dir(api_data);
res.status(response.statusCode).send(body);
return;
} else {
@@ -42,6 +44,9 @@ app.all(/.*/, (req, res) => {
res.send(body);
}
})
} else {
res.status(401).send('Unauthorized');
return;
}
});
+93 -42
View File
@@ -1,8 +1,9 @@
const express = require('express');
const WebSocket = require('ws');
const auth = require('express-basic-auth');
const os = require('os');
const { createHash } = require('crypto');
// TODO: make the code more reusable between the two endpoints
const app = express();
const port = 8355;
@@ -95,42 +96,48 @@ const hazeTranslator = {
"Bats"
]
};
app.use(auth({
authorizer: (username, password) => {
return true;
}
}));
const deviceInfo = {
// modelname: "GeoJSON_connector"
"event": "reportDeviceInfo_request",
"body": [
"third-party",
"Linux",
"dehaze",
"Firefox",
"154.0",
"GeoJSON_connector",
null,
"desktop",
"web"
]
};
// Assemble full Haze location data, can take a LONG time
app.all('/locations_full.geojson', (req, res) => {
// TODO: Implement 1wk caching of location data
// Verify Inputs
if ((!req.auth.user || !req.auth.password) && (!req.query.auth)) {
if (!req.headers['authorization']) {
res.status(401).send('Unauthorized');
return;
}
// Setup local variables for request
// Setup standard authentication variables
let hazePwHash = null;
let hazeUser = null;
let hazeSocketCounter = 0;
let requestStartTime = new Date().getTime();
if (req.query.auth) {
let paramAuth = Buffer.from(req.query.auth, 'base64').toString('utf-8');
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');
}
let authHeader = req.headers['authorization'];
let paramAuth = Buffer.from(authHeader.replace('Basic ', ''), 'base64').toString('utf-8');
hazeUser = paramAuth.split(":")[0];
hazePwHash = paramAuth.split(":")[1].replace(/\r?\n|\r/g, '');
if (!/\b[A-Fa-f0-9]{64}\b/.test(hazePwHash)) {
hazePwHash = createHash('sha256').update(hazePwHash).digest('hex');
}
const haze = new WebSocket('wss://do.ecven.com:8120/explr-mb');
let locations = [];
let failCounter = 0;
let queryComplete = false;
console.log(`Starting request at ${new Date().toISOString()} for ${hazeUser}`);
// Socket Message Handlers, defined here to use the local variables above
const sendComplete = () => {
if (!queryComplete) {
@@ -204,10 +211,32 @@ app.all('/locations_full.geojson', (req, res) => {
if (data['body']['response'] === 1) {
haze_authToken = data['body']['authToken'];
haze_username = data['body']['username'];
haze.send('{"event": "getMyLocationsRequest_request","body": [{"higlightImages": true}],"socketMessageId": ' + hazeSocketCounter++ + '}');
// TODO: add platform report
haze.send(JSON.stringify({
...deviceInfo,
"socketMessageId": ++hazeSocketCounter
}));
} else {
console.dir(req.query);
res.status(401).json({ ...data, password: req.auth.password });
res.status(401).json({ ...data });
haze.close();
res.end();
}
break;
case "reportDeviceInfo_response":
if (data['body']['response'] === 1) {
haze.send(JSON.stringify({
"event": "getMyLocationsRequest_request",
"body": [
{
"highlightImages": true
}
],
"socketMessageId": ++hazeSocketCounter
}));
} else {
console.dir(data);
res.status(500).send('Failed to report device info');
haze.close();
res.end();
}
@@ -302,26 +331,26 @@ app.all('/locations_full.geojson', (req, res) => {
// Original API, for only listing locations with minimal data
app.all('/locations.geojson', (req, res) => {
// Verify Inputs
if ((!req.auth.user || !req.auth.password) && (!req.query.auth)) {
if (!req.headers['authorization']) {
res.status(401).send('Unauthorized');
return;
}
// Query Haze API Websocket
// Setup standard authentication variables
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');
}
let hazeSocketCounter = 0;
let authHeader = req.headers['authorization'];
let paramAuth = Buffer.from(authHeader.replace('Basic ', ''), 'base64').toString('utf-8');
hazeUser = paramAuth.split(":")[0];
hazePwHash = paramAuth.split(":")[1].replace(/\r?\n|\r/g, '');
if (!/\b[A-Fa-f0-9]{64}\b/.test(hazePwHash)) {
hazePwHash = createHash('sha256').update(hazePwHash).digest('hex');
}
const haze = new WebSocket('wss://do.ecven.com:8120/explr');
// At this point we need hazeUser as the email and hazePwHas as the sha256 hashed password
// Query Haze API Websocket
console.log(`Starting request at ${new Date().toISOString()} for ${hazeUser}`);
const haze = new WebSocket('wss://do.ecven.com:8120/explr-mb');
haze.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
let haze_authToken = '', haze_username = '';
@@ -335,17 +364,39 @@ app.all('/locations.geojson', (req, res) => {
"email": hazeUser
}
],
"socketMessageId": 0
"socketMessageId": hazeSocketCounter
}));
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}');
// TODO: add platform report
haze.send(JSON.stringify({
...deviceInfo,
"socketMessageId": ++hazeSocketCounter
}));
} else {
console.dir(req.query);
res.status(401).json({ ...data, password: req.auth.password });
res.status(401).json({ ...data });
haze.close();
res.end();
}
break;
case "reportDeviceInfo_response":
if (data['body']['response'] === 1) {
haze.send(JSON.stringify({
"event": "getMyLocationsRequest_request",
"body": [
{
"highlightImages": true
}
],
"socketMessageId": ++hazeSocketCounter
}));
} else {
console.dir(data);
res.status(500).send('Failed to report device info');
haze.close();
res.end();
}
@@ -369,7 +420,7 @@ app.all('/locations.geojson', (req, res) => {
res.setHeader('Content-Type', 'application/json');
haze.close();
res.end(JSON.stringify({
...geonJsonTemplate,
...geoJsonTemplate,
features: hazeLocations
}));
} else {
@@ -381,8 +432,8 @@ app.all('/locations.geojson', (req, res) => {
break;
default:
console.dir(data);
res.status(500).send('Unexpected response from Haze API');
haze.close();
res.status(500).send('Unexpected response from Haze API');
res.end();
}
});