Files
dehaze/basicauth_serve.js
2026-04-24 16:45:54 -04:00

113 lines
6.0 KiB
JavaScript

const express = require('express');
const auth = require('express-basic-auth');
const { createHash } = require('crypto');
const app = express();
const port = 8355;
const geonJsonTemplate = {
type: "FeatureCollection",
features: [],
"marker-symbol-images": {
"star": "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 640'><path opacity='.4' fill='currentColor' d='M160 263.7L160 512C160 520.8 167.2 528 176 528L261.9 528L231.6 479.9C227.2 473 228.8 463.9 235.2 458.8L320 391.5L261.9 315.4C250.6 300.6 269.3 281.8 284.2 292.9L399.4 379.1C407.8 385.4 408 397.9 399.8 404.4L320 467.8L357.9 528L464 528C472.8 528 480 520.8 480 512L480 263.7L320 120.2L160 263.7z'/><path fill='currentColor' d='M336 70.1C326.9 61.9 313.1 61.9 304 70.1L72 278.1C62.1 286.9 61.3 302.1 70.2 312C79.1 321.9 94.2 322.7 104.1 313.8L112.1 306.6L112.1 511.9C112.1 547.2 140.8 575.9 176.1 575.9L464.1 575.9C499.4 575.9 528.1 547.2 528.1 511.9L528.1 306.6L536.1 313.8C546 322.6 561.1 321.8 570 312C578.9 302.2 578 287 568.2 278.1L528.2 242.2L528.2 152C528.2 138.7 517.5 128 504.2 128C490.9 128 480.2 138.7 480.2 152L480.2 199.2L336.2 70.1zM480 263.7L480 512C480 520.8 472.8 528 464 528L357.9 528L320 467.8L399.7 404.5C407.9 398 407.7 385.4 399.3 379.2L284.2 293C269.3 281.9 250.6 300.8 261.9 315.5L320 391.6L235.2 458.9C228.8 464 227.3 473.1 231.6 480L261.9 528.1L176 528.1C167.2 528.1 160 520.9 160 512.1L160 263.7L320 120.2L480 263.7z'/></svg>",
"star-stroked": "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'><path fill='currentColor' d='M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zm73.8 149.3c7.9-22.3 29.1-37.3 52.8-37.3l58.3 0c34.9 0 63.1 28.3 63.1 63.1 0 22.6-12.1 43.5-31.7 54.8L248 280.4c-.2 13-10.9 23.6-24 23.6-13.3 0-24-10.7-24-24l0-13.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1 0-8.4-6.8-15.1-15.1-15.1l-58.3 0c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM192 368a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM48 104a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM376 80a24 24 0 1 1 0 48 24 24 0 1 1 0-48zM48 408a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm328-24a24 24 0 1 1 0 48 24 24 0 1 1 0-48z'/></svg>"
}
};
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)) {
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);
let haze_authToken = '', haze_username = '';
switch (data['event']) {
case "connected":
haze.send(JSON.stringify({
"event": "authenticateAccount_request",
"body": [
{
"password": hazePwHash,
"email": hazeUser
}
],
"socketMessageId": 0
}));
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.auth.password });
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}`);
});