Full Data Update
This commit is contained in:
@@ -8,7 +8,7 @@ This was a quick and dirty project, and will probably get some updates slowly in
|
||||
|
||||
```bash
|
||||
npm i
|
||||
node serve.js
|
||||
node basicauth_serve.js
|
||||
```
|
||||
|
||||
To use the endpoint, replace 'EMAIL' and 'PASSWORD' with your Haze Explr account details:
|
||||
@@ -23,6 +23,4 @@ Then, make a request to the endpoint with the resulting string as the value of t
|
||||
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.
|
||||
This is from a limitation of express-basic-auth.
|
||||
`adapt.js` converts url-passed auth credentials into the basicauth server, I will refactor these in the future to use a `.env` file and better coding standards.
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Adapt URL-passed auth into basic HTTP auth for QGIS compatibility.
|
||||
|
||||
const express = require('express');
|
||||
const request = require('request');
|
||||
|
||||
const app = express();
|
||||
const port = 8356;
|
||||
|
||||
const reqOpts = {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: ''
|
||||
},
|
||||
url: 'http://localhost:8355',
|
||||
timeout: 1200000 // 20 minutes
|
||||
}
|
||||
|
||||
app.all('*', (req, res) => {
|
||||
// Verify Inputs
|
||||
if (!req.query.auth) {
|
||||
res.status(401).send('Unauthorized');
|
||||
return;
|
||||
}
|
||||
let hazePwHash = null;
|
||||
let hazeUser = null;
|
||||
if (req.query.auth) {
|
||||
request({
|
||||
...reqOpts,
|
||||
url: reqOpts.url + req.baseUrl,
|
||||
headers: {
|
||||
Authorization: `Basic ${req.query.auth}`
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
if (error) {
|
||||
res.status(500).send('Internal Server Error');
|
||||
return;
|
||||
} else if (response.statusCode !== 200) {
|
||||
res.status(response.statusCode).send(body);
|
||||
return;
|
||||
} else {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.send(body);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server is running on http://localhost:${port}`);
|
||||
});
|
||||
+243
-58
@@ -1,4 +1,5 @@
|
||||
const express = require('express');
|
||||
const WebSocket = require('ws');
|
||||
const auth = require('express-basic-auth');
|
||||
const { createHash } = require('crypto');
|
||||
|
||||
@@ -40,6 +41,58 @@ const hazeTranslator = {
|
||||
"Pathfinder",
|
||||
"Trailblazer",
|
||||
"Maven"
|
||||
],
|
||||
tag: [
|
||||
"Vicious Dogs",
|
||||
"Biohazard",
|
||||
"Radioactive",
|
||||
"Fence",
|
||||
"Rats",
|
||||
"Still Water",
|
||||
"Barbed Wire",
|
||||
"Fire",
|
||||
"Flashlight Recommended",
|
||||
"Climbing Rope Recommended",
|
||||
"Boat",
|
||||
"Electrical Hazard",
|
||||
"Helmet Recommended",
|
||||
"Boots Recommended",
|
||||
"Falling Debris",
|
||||
"Dust Mask Recommended",
|
||||
"Asbestos",
|
||||
"Extreme Temperature",
|
||||
"Squatters",
|
||||
"Risk of Violence or Crime",
|
||||
"Emotional Distress",
|
||||
"Landmines",
|
||||
"Respirator Recommended",
|
||||
"Active Security",
|
||||
"No Trespassing Sign",
|
||||
"Private Property Sign",
|
||||
"Flood Risk",
|
||||
"Locked",
|
||||
"Dead Air",
|
||||
"Unstable Structure",
|
||||
"Black Mold",
|
||||
"Ticks",
|
||||
"Mosquitoes",
|
||||
"Razor Wire",
|
||||
"Fiberglass",
|
||||
"Bears",
|
||||
"Wolves",
|
||||
"Wildlife",
|
||||
"Broken Glass",
|
||||
"Scorpions",
|
||||
"Snakes",
|
||||
"Venomous Spiders",
|
||||
"Karens Present",
|
||||
"Gloves Recommended",
|
||||
"Boarded Up",
|
||||
"Thorns",
|
||||
"Dangerous Hights",
|
||||
"Hazmat Suit Recommended",
|
||||
"Heavy Overgrowth",
|
||||
"Bats"
|
||||
]
|
||||
};
|
||||
app.use(auth({
|
||||
@@ -48,13 +101,15 @@ app.use(auth({
|
||||
}
|
||||
}));
|
||||
|
||||
app.all('/locations.geojson', (req, res) => {
|
||||
// Assemble full Haze location data, can take a LONG time
|
||||
app.all('/locations_full.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
|
||||
|
||||
// Setup local variables for request
|
||||
let hazePwHash = null;
|
||||
let hazeUser = null;
|
||||
let hazeSocketCounter = 0;
|
||||
@@ -71,8 +126,64 @@ app.all('/locations.geojson', (req, res) => {
|
||||
hazePwHash = createHash('sha256').update(req.auth.password).digest('hex');
|
||||
}
|
||||
}
|
||||
const haze = new WebSocket('wss://do.ecven.com:8120/explr');
|
||||
const haze = new WebSocket('wss://do.ecven.com:8120/explr-mb');
|
||||
let locations = [];
|
||||
let failCounter = 0;
|
||||
let queryComplete = false;
|
||||
|
||||
// Socket Message Handlers, defined here to use the local variables above
|
||||
const sendComplete = () => {
|
||||
if (!queryComplete) {
|
||||
queryComplete = true;
|
||||
haze.close();
|
||||
let testTime = (new Date().getTime() - requestStartTime);
|
||||
const countExported = locations.filter(location => location && location.completed).length;
|
||||
console.log(`${(new Date().getTime() - requestStartTime)/1000}s | FAILS: ${failCounter} | TIMEOUT: ${testTime} | TOTAL LOCATIONS: ${locations.length} | EXPORTED: ${countExported} | TIMEDOUT: ${locations.length - countExported - failCounter}`);
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(JSON.stringify({
|
||||
...geoJsonTemplate,
|
||||
features: locations.map(location => ({
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [location['longitude'], location['latitude']]
|
||||
},
|
||||
properties: {
|
||||
id: location['id'],
|
||||
title: location['name'],
|
||||
"marker-symbol": location['isUnconfirmedLocation'] === 1 ? "star-stroked" : "star",
|
||||
author: location['author'] || '',
|
||||
explored: location['isExplored'] || false,
|
||||
confirmed: location['isConfirmed'] || false,
|
||||
category: location['category'] || '',
|
||||
level: location['level'] || '',
|
||||
rating: location['rating'] || '',
|
||||
difficulty: location['difficulty'] || '',
|
||||
comments: location['comments'] || [],
|
||||
querySuccess: location['completed']
|
||||
}
|
||||
}))
|
||||
}));
|
||||
}
|
||||
}
|
||||
const queryLocation = (index) => {
|
||||
haze.send(locations[index]['requestQuery']);
|
||||
setTimeout(() => {
|
||||
if (locations[index]['completed'] === 0) {
|
||||
console.log(`Timeout on ${locations[index]['id']}}`);
|
||||
locations[index]['completed'] = -1; // mark as failed
|
||||
failCounter++;
|
||||
let nextIndex = locations.findIndex(location => location && location.completed === 0);
|
||||
if (locations.every(location => location && location.completed !== 0) || nextIndex === -1) {
|
||||
sendComplete();
|
||||
} else {
|
||||
queryLocation(nextIndex);
|
||||
}
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
// These are the socket event handlers, in order of expected use
|
||||
haze.addEventListener('message', (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
let haze_authToken = '', haze_username = '';
|
||||
@@ -103,15 +214,9 @@ app.all('/locations.geojson', (req, res) => {
|
||||
break;
|
||||
case "getMyLocationsRequest_response":
|
||||
if (data['body']['response'] === 1) {
|
||||
// locations = data['body']['locations'].map(location => {
|
||||
// return {
|
||||
// id: location['id'],
|
||||
// title: location['name'],
|
||||
// completed: false
|
||||
// };
|
||||
// });
|
||||
data['body']['locations'].forEach(location => {
|
||||
locations[hazeSocketCounter++] = {
|
||||
hazeSocketCounter++;
|
||||
locations[hazeSocketCounter] = {
|
||||
id: location['id'],
|
||||
title: location['name'],
|
||||
latitude: location['coordinates']['latitude'],
|
||||
@@ -119,21 +224,17 @@ app.all('/locations.geojson', (req, res) => {
|
||||
isExplored: location['explored'] > 0,
|
||||
isConfirmed: location['isUnconfirmedLocation'] !== 1,
|
||||
category: hazeTranslator.category[location['locationCategory']],
|
||||
completed: false
|
||||
}
|
||||
});
|
||||
|
||||
// need to make the socketIDs dynamic and handle completed status before returning final payload
|
||||
// FIX: Currently throwing response 2 "User does not have access to location."
|
||||
locations.forEach((location, index) => {
|
||||
if (location) {
|
||||
haze.send(JSON.stringify({
|
||||
rawBasicData: JSON.stringify(location),
|
||||
requestQuery: JSON.stringify({
|
||||
event: "getLocation_request",
|
||||
body: locations.map(location => location.id),
|
||||
socketMessageId: index
|
||||
}));
|
||||
body: [ location['id'] ],
|
||||
socketMessageId: hazeSocketCounter
|
||||
}),
|
||||
completed: 0
|
||||
}
|
||||
});
|
||||
queryLocation(locations.findIndex(location => location && location.completed === 0));
|
||||
|
||||
} else {
|
||||
console.dir(data);
|
||||
res.status(500).send('Failed to retrieve locations');
|
||||
@@ -143,14 +244,29 @@ app.all('/locations.geojson', (req, res) => {
|
||||
break;
|
||||
case "getLocation_response":
|
||||
if (data['body']['response'] === 1) {
|
||||
let locationTags = {};
|
||||
data['body']['location']['locationRating']['ratingItemsList'].map(tag => {
|
||||
locationTags[hazeTranslator.tag[tag['id']] ? hazeTranslator.tag[tag['id']] : tag['id']] = tag['count'];
|
||||
});
|
||||
locations[data['socketMessageId']] = {
|
||||
...locations[data['socketMessageId']],
|
||||
completed: true,
|
||||
completed: 1,
|
||||
author: `${data['body']['location']['submittorUserDatas']['username']} (${data['body']['location']['submittorUserDatas']['email']})`,
|
||||
rating: hazeTranslator.rating[data['body']['location']['locationRating']['overallRating']],
|
||||
difficulty: hazeTranslator.difficulty[data['body']['location']['locationRating']['difficultyRating']],
|
||||
level: hazeTranslator.level[data['body']['location']['locationRating']['levelRating']],
|
||||
// TODO: use body.location.locationRating.ratingItemsList for location tags
|
||||
tags: locationTags,
|
||||
images: [
|
||||
... data['body']['location']['gallery'].map(image => ({
|
||||
id: image['id'],
|
||||
mimetype: `image/${image['mediaType']}`,
|
||||
author: `${image['uploaderData']['username']} (${image['uploaderData']['email']})`,
|
||||
url: image['url'],
|
||||
thumbnail: image['thumbnailUrl'],
|
||||
likes: image['likes'],
|
||||
date: image['uploadDate'],
|
||||
}))
|
||||
],
|
||||
comments: data['body']['location']['locationCommentsAndCommunityVotes'].map(comment => ({
|
||||
id: comment['id'],
|
||||
text: comment['comment'],
|
||||
@@ -158,43 +274,111 @@ app.all('/locations.geojson', (req, res) => {
|
||||
author: comment['submittor']['username'],
|
||||
}))
|
||||
};
|
||||
let testTime = (new Date().getTime() - requestStartTime) > 30000; // 30s timeout
|
||||
if (locations.every(location => location && location.completed) || testTime) {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
haze.close();
|
||||
res.end(JSON.stringify({
|
||||
...geoJsonTemplate,
|
||||
features: locations.map(location => ({
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [location['longitude'], location['latitude']]
|
||||
},
|
||||
properties: {
|
||||
id: location['id'],
|
||||
title: location['name'],
|
||||
"marker-symbol": location['isUnconfirmedLocation'] === 1 ? "star-stroked" : "star",
|
||||
author: location['author'] || '',
|
||||
explored: location['isExplored'] || false,
|
||||
confirmed: location['isConfirmed'] || false,
|
||||
category: location['category'] || '',
|
||||
level: location['level'] || '',
|
||||
rating: location['rating'] || '',
|
||||
difficulty: location['difficulty'] || '',
|
||||
comments: location['comments'] || [],
|
||||
querySuccess: location['completed']
|
||||
}
|
||||
}))
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
console.dir(data);
|
||||
// res.status(500).send('Failed to retrieve locations');
|
||||
// haze.close();
|
||||
// res.end();
|
||||
console.log(`Failure on ${locations[data['socketMessageId']]['id']}: ${data['body']['responseDetails']}`);
|
||||
locations[data['socketMessageId']]['completed'] = -1; // mark as failed
|
||||
failCounter++;
|
||||
}
|
||||
// Completion Check and increment
|
||||
let nextIndex = locations.findIndex(location => location && location.completed === 0);
|
||||
if (locations.every(location => location && location.completed !== 0) || nextIndex === -1) {
|
||||
sendComplete();
|
||||
} else {
|
||||
queryLocation(nextIndex);
|
||||
}
|
||||
break;
|
||||
case "ping":
|
||||
console.log('Ping received from Haze API');
|
||||
break;
|
||||
default:
|
||||
console.log(JSON.stringify(data, null, 2));
|
||||
res.status(500).send('Unexpected response from Haze API');
|
||||
haze.close();
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 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)) {
|
||||
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');
|
||||
@@ -204,6 +388,7 @@ app.all('/locations.geojson', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server is running on http://localhost:${port}`);
|
||||
});
|
||||
|
||||
Generated
+499
-1
@@ -11,7 +11,9 @@
|
||||
"dependencies": {
|
||||
"crypto": "^1.0.1",
|
||||
"express": "^5.2.1",
|
||||
"express-basic-auth": "^1.2.1"
|
||||
"express-basic-auth": "^1.2.1",
|
||||
"request": "^2.88.2",
|
||||
"ws": "^8.21.1"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
@@ -27,6 +29,61 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.15.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
|
||||
"integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/asn1": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
|
||||
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/aws4": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz",
|
||||
"integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/basic-auth": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
|
||||
@@ -39,6 +96,15 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
|
||||
@@ -101,6 +167,24 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
|
||||
@@ -141,6 +225,12 @@
|
||||
"node": ">=6.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/crypto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
|
||||
@@ -148,6 +238,18 @@
|
||||
"deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
@@ -165,6 +267,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
@@ -188,6 +299,16 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
@@ -300,6 +421,33 @@
|
||||
"basic-auth": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
|
||||
"engines": [
|
||||
"node >=0.6.0"
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
|
||||
@@ -321,6 +469,50 @@
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data/node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data/node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
@@ -385,6 +577,15 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
@@ -397,6 +598,29 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/har-validator": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
|
||||
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
|
||||
"deprecated": "this library is no longer supported",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.3",
|
||||
"har-schema": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
@@ -441,6 +665,21 @@
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8",
|
||||
"npm": ">=1.3.7"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
|
||||
@@ -478,6 +717,57 @@
|
||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json-schema": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
||||
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
|
||||
"license": "(AFL-2.1 OR BSD-3-Clause)"
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jsprim": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
|
||||
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.4.0",
|
||||
"verror": "1.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
@@ -548,6 +838,15 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||
@@ -600,6 +899,12 @@
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
@@ -613,6 +918,27 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/psl": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
|
||||
"integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"punycode": "^2.3.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/lupomontero"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.15.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
|
||||
@@ -652,6 +978,68 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/request": {
|
||||
"version": "2.88.2",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
|
||||
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
|
||||
"deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/request/node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/request/node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/request/node_modules/qs": {
|
||||
"version": "6.5.5",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz",
|
||||
"integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/router": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
||||
@@ -803,6 +1191,31 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/sshpk": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
|
||||
"integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
},
|
||||
"bin": {
|
||||
"sshpk-conv": "bin/sshpk-conv",
|
||||
"sshpk-sign": "bin/sshpk-sign",
|
||||
"sshpk-verify": "bin/sshpk-verify"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/statuses": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||
@@ -821,6 +1234,37 @@
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
|
||||
"license": "Unlicense"
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||
@@ -844,6 +1288,25 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/uri-js": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||
"deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
@@ -853,11 +1316,46 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
|
||||
"engines": [
|
||||
"node >=0.6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.21.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
|
||||
"integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -16,6 +16,8 @@
|
||||
"dependencies": {
|
||||
"crypto": "^1.0.1",
|
||||
"express": "^5.2.1",
|
||||
"express-basic-auth": "^1.2.1"
|
||||
"express-basic-auth": "^1.2.1",
|
||||
"request": "^2.88.2",
|
||||
"ws": "^8.21.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
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,<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.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}`);
|
||||
});
|
||||
Reference in New Issue
Block a user