retropilot-server/src/server/router/legacy.js

518 lines
18 KiB
JavaScript
Raw Normal View History

2022-01-12 08:02:30 -07:00
import bodyParser from 'body-parser';
import crypto from 'crypto';
2022-03-22 09:14:08 -06:00
import express from 'express';
2022-01-12 08:02:30 -07:00
import log4js from 'log4js';
2022-03-22 09:14:08 -06:00
import { validateJWT } from '../controllers/authentication';
2022-01-12 08:02:30 -07:00
import deviceController from '../controllers/devices';
2022-03-22 09:14:08 -06:00
import storageController from '../controllers/storage';
import { getAccountFromId } from '../controllers/users';
2022-03-24 16:05:05 -06:00
import { getDevice } from '../middlewares/devices';
2022-03-22 09:14:08 -06:00
const logger = log4js.getLogger();
2022-01-12 08:02:30 -07:00
const router = express.Router();
function runAsyncWrapper(callback) {
2022-01-08 17:38:41 -07:00
return function wrapper(req, res, next) {
2022-01-07 18:35:55 -07:00
callback(req, res, next)
.catch(next);
};
}
2022-03-22 07:03:17 -06:00
// TODO(cameron): clean up this mess into separate files
// DRIVE & BOOT/CRASH LOG FILE UPLOAD HANDLING
router.put('/backend/post_upload', bodyParser.raw({
2022-01-07 18:35:55 -07:00
inflate: true,
limit: '100000kb',
2022-01-08 13:43:57 -07:00
type: '*/*',
}), runAsyncWrapper(async (req, res) => {
2022-01-08 17:57:15 -07:00
const buf = Buffer.from(req.body.toString('binary'), 'binary');
2022-01-07 18:35:55 -07:00
logger.info(`HTTP.PUT /backend/post_upload for dongle ${req.query.dongleId} with body length: ${buf.length}`);
2022-01-08 17:57:15 -07:00
const {
dir: directory,
dongleId,
file: filename,
ts,
} = req.query;
2022-01-07 18:35:55 -07:00
2022-01-08 17:57:15 -07:00
const isDriveFile = filename.indexOf('boot') !== 0 && filename.indexOf('crash') !== 0;
if (isDriveFile) {
2022-01-07 18:35:55 -07:00
logger.info(`HTTP.PUT /backend/post_upload DRIVE upload with filename: ${filename}, directory: ${directory}, token: ${req.query.token}`);
2022-01-08 17:57:15 -07:00
} else {
2022-01-07 18:35:55 -07:00
logger.info(`HTTP.PUT /backend/post_upload BOOT or CRASH upload with filename: ${filename}, token: ${req.query.token}`);
2022-01-08 17:57:15 -07:00
}
2022-01-08 17:38:41 -07:00
2022-03-24 17:36:42 -06:00
const token = crypto
.createHmac('sha256', process.env.APP_SALT)
.update(dongleId + filename + directory + ts)
.digest('hex');
2022-01-08 17:57:15 -07:00
if (token !== req.query.token) {
logger.error(`HTTP.PUT /backend/post_upload token mismatch (${token} vs ${req.query.token})`);
return res.status(400).send('Malformed request');
2022-01-07 18:35:55 -07:00
}
2022-01-08 17:57:15 -07:00
logger.info('HTTP.PUT /backend/post_upload permissions checked, calling moveUploadedFile');
const moveResult = storageController.moveUploadedFile(buf, directory, filename);
2022-01-08 17:57:15 -07:00
if (!moveResult) {
logger.error('HTTP.PUT /backend/post_upload moveUploadedFile failed');
return res.status(500).send('Internal Server Error');
}
logger.info(`HTTP.PUT /backend/post_upload successfully uploaded to ${moveResult}`);
return res.status(200).json(['OK']);
2022-01-07 18:35:55 -07:00
}));
2022-01-07 18:35:55 -07:00
// RETURN THE PAIRING STATUS
2022-03-24 16:05:05 -06:00
router.get('/v1.1/devices/:dongleId', getDevice, runAsyncWrapper(async (req, res) => {
2022-03-23 17:55:01 -06:00
const { authorization } = req.headers;
2022-01-07 18:35:55 -07:00
const { dongleId } = req.params;
2022-03-23 17:55:01 -06:00
logger.info(`HTTP.DEVICES called for ${dongleId}`);
2022-03-24 16:05:05 -06:00
const { device } = req;
2022-01-07 18:35:55 -07:00
if (!device) {
logger.info(`HTTP.DEVICES device ${dongleId} not found`);
return res.status(200).json({
is_paired: false,
prime: false,
prime_type: 0,
});
2022-01-07 18:35:55 -07:00
}
2022-03-23 17:55:01 -06:00
const {
account_id: accountId,
public_key: publicKey,
} = device;
const decoded = publicKey
? await validateJWT(authorization, publicKey)
2022-01-08 16:07:09 -07:00
: null;
2022-03-23 17:55:01 -06:00
if ((!decoded || decoded.identity !== dongleId)) {
logger.info('HTTP.DEVICES JWT authorization failed', {
token: authorization,
device,
decoded,
});
2022-03-24 16:05:05 -06:00
return res.status(401).send('Unauthorised.');
2022-01-07 18:35:55 -07:00
}
const PrimeType = {
None: 0,
Magenta: 1,
Lite: 2,
};
const isPaired = accountId !== 0;
2022-03-23 17:55:01 -06:00
const response = {
is_paired: isPaired,
/*
* Whether the account is subscribed to prime. Removed in OP 0.8.13. Replaced by `prime_type`.
*/
prime: isPaired,
/*
* The type of prime subscription the account is subscribed to.
*/
prime_type: isPaired ? PrimeType.Lite : PrimeType.None,
2022-03-23 17:55:01 -06:00
};
logger.info(`HTTP.DEVICES for ${dongleId} returning: ${JSON.stringify(response)}`);
2022-01-08 17:38:41 -07:00
return res.status(200).json(response);
2022-01-07 18:35:55 -07:00
}));
2022-01-07 18:35:55 -07:00
// RETURN STATS FOR DASHBOARD
2022-03-24 16:05:05 -06:00
router.get('/v1.1/devices/:dongleId/stats', getDevice, runAsyncWrapper(async (req, res) => {
2022-01-07 18:35:55 -07:00
const { dongleId } = req.params;
2022-03-23 17:55:01 -06:00
logger.info(`HTTP.STATS called for ${dongleId}`);
2022-01-07 18:35:55 -07:00
const stats = {
all: {
routes: 0,
distance: 0,
2022-01-08 13:43:57 -07:00
minutes: 0,
2022-01-07 18:35:55 -07:00
},
week: {
routes: 0,
distance: 0,
2022-01-08 13:43:57 -07:00
minutes: 0,
},
2022-01-07 18:35:55 -07:00
};
2022-03-24 16:05:05 -06:00
const { device } = req;
2022-01-07 18:35:55 -07:00
if (!device) {
logger.info(`HTTP.STATS device ${dongleId} not found`);
2022-03-24 16:05:05 -06:00
return res.status(404).send('Not found.');
2022-01-07 18:35:55 -07:00
}
2022-03-23 17:55:01 -06:00
const { public_key: publicKey } = device;
const { authorization } = req.headers;
2022-03-24 16:05:05 -06:00
if (!authorization) {
logger.info(`HTTP.STATS JWT missing authorization, dongleId: ${dongleId}`);
return res.status(401).send('Unauthorised.');
}
2022-01-08 16:07:09 -07:00
const decoded = device.public_key
2022-03-23 17:55:01 -06:00
? await validateJWT(authorization, publicKey)
2022-01-08 16:07:09 -07:00
: null;
2022-01-07 18:35:55 -07:00
2022-03-23 17:55:01 -06:00
if ((!decoded || decoded.identity !== dongleId)) {
logger.info(`HTTP.STATS JWT authorization failed, token: ${authorization} device: ${JSON.stringify(device)}, decoded: ${JSON.stringify(decoded)}`);
2022-03-24 16:05:05 -06:00
return res.status(403).send('Forbidden.');
2022-01-07 18:35:55 -07:00
}
2022-01-09 03:50:27 -07:00
// TODO reimplement weekly stats
2022-03-22 09:14:08 -06:00
// const statresult = await models.get('SELECT COUNT(*) as routes, ROUND(SUM(distance_meters)/1609.34) as distance, ROUND(SUM(duration)/60) as duration FROM drives WHERE dongle_id=?', device.dongle_id);
// if (statresult != null && statresult.routes != null) {
// stats.all.routes = statresult.routes;
// stats.all.distance = statresult.distance != null ? statresult.distance : 0;
// stats.all.minutes = statresult.duration != null ? statresult.duration : 0;
// }
//
// // this determines the date at 00:00:00 UTC of last monday (== beginning of the current "ISO"week)
// const d = new Date();
// const day = d.getDay();
// const diff = d.getDate() - day + (day === 0 ? -6 : 1);
// const lastMonday = new Date(d.setDate(diff));
// lastMonday.setHours(0, 0, 0, 0);
//
// const statresultweek = await models.get('SELECT COUNT(*) as routes, ROUND(SUM(distance_meters)/1609.34) as distance, ROUND(SUM(duration)/60) as duration FROM drives WHERE dongle_id=? AND drive_date >= ?', device.dongle_id, lastMonday.getTime());
// if (statresultweek != null && statresultweek.routes != null) {
// stats.week.routes = statresultweek.routes;
// stats.week.distance = statresultweek.distance != null ? statresultweek.distance : 0;
// stats.week.minutes = statresultweek.duration != null ? statresultweek.duration : 0;
// }
2022-01-07 18:35:55 -07:00
2022-03-23 17:55:01 -06:00
logger.info(`HTTP.STATS for ${dongleId} returning: ${JSON.stringify(stats)}`);
2022-01-08 17:38:41 -07:00
return res.status(200).json(stats);
2022-01-07 18:35:55 -07:00
}));
// RETURN USERNAME & POINTS FOR DASHBOARD
2022-03-24 16:05:05 -06:00
router.get('/v1/devices/:dongleId/owner', getDevice, runAsyncWrapper(async (req, res) => {
2022-01-07 18:35:55 -07:00
const { dongleId } = req.params;
2022-03-23 17:55:01 -06:00
logger.info(`HTTP.OWNER called for ${dongleId}`);
2022-03-24 16:05:05 -06:00
const { device } = req;
2022-01-07 18:35:55 -07:00
if (!device) {
logger.info(`HTTP.OWNER device ${dongleId} not found`);
2022-01-08 17:38:41 -07:00
return res.status(200).json({ username: 'unregisteredDevice', points: 0 });
2022-01-07 18:35:55 -07:00
}
2022-03-24 16:05:05 -06:00
const { authorization } = req.headers;
if (!authorization) {
logger.info(`HTTP.OWNER JWT missing authorization, dongleId: ${dongleId}`);
return res.status(401).send('Unauthorised.');
}
2022-01-08 17:38:41 -07:00
const decoded = device.public_key
2022-03-24 16:05:05 -06:00
? await validateJWT(authorization, device.public_key)
2022-01-08 17:38:41 -07:00
: null;
2022-03-23 17:55:01 -06:00
if ((!decoded || decoded.identity !== dongleId)) {
2022-03-24 16:05:05 -06:00
logger.info(`HTTP.OWNER JWT authorization failed, token: ${authorization.authorization} device: ${JSON.stringify(device)}, decoded: ${JSON.stringify(decoded)}`);
return res.status(403).send('Forbidden.');
2022-01-07 18:35:55 -07:00
}
let owner = '';
2022-03-22 09:14:08 -06:00
const points = 0;
2022-01-07 18:35:55 -07:00
2022-03-22 09:14:08 -06:00
let account = await getAccountFromId(device.account_id);
2022-01-09 03:50:27 -07:00
if (account != null && account.dataValues != null) {
2022-03-22 09:14:08 -06:00
account = account.dataValues;
2022-01-08 17:38:41 -07:00
[owner] = account.email.split('@');
2022-01-09 03:50:27 -07:00
// TODO reimplement "points"
2022-03-22 09:14:08 -06:00
// const stats = await models.all('SELECT SUM(distance_meters) as points FROM drives WHERE dongle_id IN (SELECT dongle_id FROM devices WHERE account_id=?)', account.id);
// if (stats != null && stats.points != null) {
// points = stats.points;
// }
2022-01-07 18:35:55 -07:00
}
2022-01-07 18:35:55 -07:00
const response = { username: owner, points };
2022-03-23 17:55:01 -06:00
logger.info(`HTTP.OWNER for ${dongleId} returning: ${JSON.stringify(response)}`);
2022-01-08 17:38:41 -07:00
return res.status(200).json(response);
2022-01-07 18:35:55 -07:00
}));
2022-01-07 18:35:55 -07:00
async function upload(req, res) {
2022-01-08 17:57:15 -07:00
let { path } = req.query;
2022-01-07 18:35:55 -07:00
const { dongleId } = req.params;
2022-03-24 16:05:05 -06:00
2022-03-23 17:55:01 -06:00
logger.info(`HTTP.UPLOAD_URL called for ${dongleId} and file ${path}: ${JSON.stringify(req.headers)}`);
2022-03-24 16:05:05 -06:00
const { device } = req;
2022-01-07 18:35:55 -07:00
if (!device) {
logger.info(`HTTP.UPLOAD_URL device ${dongleId} not found or not linked to an account / refusing uploads`);
2022-03-23 17:55:01 -06:00
return res.status(404).send('Not Found.');
2022-01-07 18:35:55 -07:00
}
2022-03-24 16:05:05 -06:00
const { authorization } = req.headers;
if (!authorization) {
logger.info(`HTTP.UPLOAD_URL JWT missing authorization, dongleId: ${dongleId}`);
return res.status(401).send('Unauthorised.');
}
2022-01-08 17:57:15 -07:00
const decoded = device.public_key
2022-03-24 16:05:05 -06:00
? await validateJWT(authorization, device.public_key)
2022-03-24 07:51:39 -06:00
.catch((err) => logger.error(err))
2022-01-08 17:57:15 -07:00
: null;
2022-03-23 17:55:01 -06:00
if ((!decoded || decoded.identity !== dongleId)) {
2022-03-24 16:05:05 -06:00
logger.info(`HTTP.UPLOAD_URL JWT authorization failed, token: ${authorization} device: ${JSON.stringify(device)}, decoded: ${JSON.stringify(decoded)}`);
return res.status(403).send('Forbidden.');
2022-01-07 18:35:55 -07:00
}
2022-03-24 07:51:39 -06:00
await deviceController
.updateLastPing(dongleId)
.catch((err) => logger.error(err));
2022-01-07 18:35:55 -07:00
let responseUrl = null;
const ts = Date.now(); // we use this to make sure old URLs cannot be reused (timeout after 60min)
2022-03-24 17:36:42 -06:00
const dongleIdHash = crypto
.createHmac('sha256', process.env.APP_SALT)
.update(dongleId)
.digest('hex');
2022-01-07 18:35:55 -07:00
// boot log upload
if (path.indexOf('boot/') === 0 || path.indexOf('crash/') === 0 || path.indexOf('bootlog.bz2') > 0) {
if (path.indexOf('bootlog.bz2') > 0) { // pre-op 0.8 way of uploading bootlogs
// file 2020-09-30--08-09-13--0/bootlog.bz2 to something like: boot/2021-05-11--03-03-38.bz2
path = `boot/${path.split('--')[0]}--${path.split('--')[1]}.bz2`;
}
2022-01-07 18:35:55 -07:00
const filename = path.replace('/', '-');
2022-01-07 18:35:55 -07:00
// TODO, allow multiple types
const uploadType = path.indexOf('boot/') === 0 ? 'boot' : 'crash';
2022-01-07 18:35:55 -07:00
// "boot-2021-04-12--01-45-30.bz" for example
const directory = `${dongleId}/${dongleIdHash}/${uploadType}`;
2022-03-24 17:36:42 -06:00
const token = crypto
.createHmac('sha256', process.env.APP_SALT)
.update(dongleId + filename + directory + ts)
.digest('hex');
responseUrl = `${process.env.BASE_UPLOAD_URL}?file=${filename}&dir=${directory}&dongleId=${dongleId}&ts=${ts}&token=${token}`;
2022-01-07 18:35:55 -07:00
logger.info(`HTTP.UPLOAD_URL matched '${uploadType}' file upload, constructed responseUrl: ${responseUrl}`);
2022-01-08 13:43:57 -07:00
} else {
2022-01-07 18:35:55 -07:00
// "2021-04-12--01-44-25--0/qlog.bz2" for example
const subdirPosition = path.split('--', 2).join('--').length;
const filenamePosition = path.indexOf('/');
if (subdirPosition > 0 && filenamePosition > subdirPosition) {
const driveName = `${path.split('--')[0]}--${path.split('--')[1]}`;
2022-01-08 17:57:15 -07:00
const segment = parseInt(path.split('--')[2].substr(0, path.split('--')[2].indexOf('/')), 10);
2022-01-07 18:35:55 -07:00
let directory = `${path.split('--')[0]}--${path.split('--')[1]}/${segment}`;
const filename = path.split('/')[1];
let validRequest = false;
if ((filename === 'fcamera.hevc' || filename === 'qcamera.ts' || filename === 'dcamera.hevc' || filename === 'rlog.bz2' || filename === 'qlog.bz2' || filename === 'ecamera.hevc')
2022-01-08 17:57:15 -07:00
&& (!Number.isNaN(segment) || (segment > 0 && segment < 1000))) {
2022-01-07 18:35:55 -07:00
validRequest = true;
}
if (!validRequest) {
logger.error(`HTTP.UPLOAD_URL invalid filename (${filename}) or invalid segment (${segment}), responding with HTTP 400`);
2022-03-23 17:55:01 -06:00
return res.status(400).send('Malformed Request.');
2022-01-07 18:35:55 -07:00
}
2022-03-24 17:36:42 -06:00
const driveIdentifierHash = crypto
.createHmac('sha256', process.env.APP_SALT)
.update(driveName)
.digest('hex');
2022-01-07 18:35:55 -07:00
directory = `${dongleId}/${dongleIdHash}/${driveIdentifierHash}/${directory}`;
2022-03-24 17:36:42 -06:00
const token = crypto
.createHmac('sha256', process.env.APP_SALT)
.update(dongleId + filename + directory + ts)
.digest('hex');
responseUrl = `${process.env.BASE_UPLOAD_URL}?file=${filename}&dir=${directory}&dongleId=${dongleId}&ts=${ts}&token=${token}`;
2022-01-07 18:35:55 -07:00
logger.info(`HTTP.UPLOAD_URL matched 'drive' file upload, constructed responseUrl: ${responseUrl}`);
2022-03-22 09:14:08 -06:00
const drive = await deviceController.getDriveFromIdentifier(dongleId, driveName)
.catch((err) => {
logger.warn('drive failed to make', err);
});
2022-01-21 16:36:48 -07:00
2022-03-22 09:14:08 -06:00
logger.info('drive value', drive);
logger.info('drive name:', driveName);
2022-01-21 16:36:48 -07:00
2022-03-24 17:36:42 -06:00
if (!drive) {
2022-03-22 09:14:08 -06:00
logger.info('CREATING NEW DRIVE');
2022-01-07 18:35:55 -07:00
// create a new drive
const timeSplit = driveName.split('--');
const timeString = `${timeSplit[0]} ${timeSplit[1].replace(/-/g, ':')}`;
2022-01-21 16:36:48 -07:00
const driveResult = await deviceController.updateOrCreateDrive(dongleId, driveName, {
max_segment: segment,
duration: 0,
distance_meters: 0,
filesize: 0,
upload_complete: false,
is_processed: false,
drive_date: Date.parse(timeString),
created: Date.now(),
last_upload: Date.now(),
is_preserved: false,
is_deleted: false,
is_physically_removed: false,
2022-03-22 09:14:08 -06:00
});
await deviceController.updateOrCreateDriveSegment(dongleId, driveName, segment, {
duration: 0,
distance_meters: 0,
upload_complete: false,
is_processed: false,
is_stalled: false,
created: Date.now(),
2022-03-22 09:14:08 -06:00
});
2022-01-07 18:35:55 -07:00
logger.info(`HTTP.UPLOAD_URL created new drive #${JSON.stringify(driveResult.lastID)}`);
2022-01-08 13:43:57 -07:00
} else {
2022-03-22 09:14:08 -06:00
logger.info('UPDATING DRIVE');
await deviceController.updateOrCreateDrive(dongleId, driveName, {
max_segment: Math.max(drive.max_segment, segment),
upload_complete: false,
is_processed: false,
last_upload: Date.now(),
2022-03-22 09:14:08 -06:00
});
2022-03-22 09:14:08 -06:00
await deviceController.updateOrCreateDriveSegment(dongleId, driveName, segment, {
duration: 0,
distance_meters: 0,
upload_complete: false,
is_processed: false,
is_stalled: false,
created: Date.now(),
});
2022-01-07 18:35:55 -07:00
logger.info(`HTTP.UPLOAD_URL updated existing drive: ${JSON.stringify(drive)}`);
}
}
2022-01-07 18:35:55 -07:00
}
2021-12-30 18:22:34 -07:00
2022-03-24 17:36:42 -06:00
if (!responseUrl) {
2022-01-07 18:35:55 -07:00
logger.error('HTTP.UPLOAD_URL unable to match request, responding with HTTP 400');
2022-01-08 17:57:15 -07:00
return res.status(400).send('Malformed Request.');
2022-01-07 18:35:55 -07:00
}
return res
.status(200)
.append('Content-Type', 'application/octet-stream')
.json({ url: responseUrl, headers: { 'Content-Type': 'application/octet-stream' } });
2022-01-07 18:35:55 -07:00
}
2021-12-30 18:22:34 -07:00
// DRIVE & BOOT/CRASH LOG FILE UPLOAD URL REQUEST
router.get('/v1.3/:dongleId/upload_url', getDevice, upload);
router.get('/v1.4/:dongleId/upload_url', getDevice, upload);
// DEVICE REGISTRATION OR RE-ACTIVATION
2022-01-07 18:35:55 -07:00
router.post('/v2/pilotauth/', bodyParser.urlencoded({ extended: true }), async (req, res) => {
2022-03-23 17:55:01 -06:00
/* eslint-disable no-unused-vars */
2022-03-02 19:37:57 -07:00
const {
2022-03-23 17:55:01 -06:00
imei: imei1,
imei2,
2022-03-02 19:37:57 -07:00
serial,
public_key: publicKey,
2022-03-22 09:14:08 -06:00
register_token: registerToken,
2022-03-02 19:37:57 -07:00
} = req.query;
2022-03-23 17:55:01 -06:00
/* eslint-enable no-unused-vars */
2022-01-08 17:57:15 -07:00
if (
2022-03-24 16:05:05 -06:00
!serial || serial.length < 5
|| !publicKey || publicKey.length < 5
|| !registerToken || registerToken.length < 5
2022-01-08 17:57:15 -07:00
) {
2022-01-07 18:35:55 -07:00
logger.error(`HTTP.V2.PILOTAUTH a required parameter is missing or empty ${JSON.stringify(req.query)}`);
2022-01-08 17:57:15 -07:00
return res.status(400).send('Malformed Request.');
2022-01-07 18:35:55 -07:00
}
2022-03-22 09:14:08 -06:00
const decoded = await validateJWT(registerToken, publicKey);
2022-01-08 16:07:09 -07:00
if (!decoded || !decoded.register) {
2022-01-07 18:35:55 -07:00
logger.error(`HTTP.V2.PILOTAUTH JWT token is invalid (${JSON.stringify(decoded)})`);
2022-03-24 16:05:05 -06:00
return res.status(401).send('Unauthorised.');
2022-01-07 18:35:55 -07:00
}
2022-03-22 09:14:08 -06:00
const device = await deviceController.getDeviceFromSerial(serial);
2022-03-24 16:05:05 -06:00
if (!device) {
2022-01-07 18:35:55 -07:00
logger.info(`HTTP.V2.PILOTAUTH REGISTERING NEW DEVICE (${imei1}, ${serial})`);
2022-01-08 17:57:15 -07:00
// TODO: rewrite without while (true) loop
// eslint-disable-next-line no-constant-condition
2022-01-07 18:35:55 -07:00
while (true) {
2022-03-24 17:36:42 -06:00
const dongleId = crypto
.randomBytes(4)
.toString('hex');
2022-03-22 09:14:08 -06:00
const isDongleIdTaken = await deviceController.getDeviceFromDongleId(dongleId);
2022-03-23 17:55:01 -06:00
if (isDongleIdTaken) {
continue;
}
2022-03-23 17:55:01 -06:00
const newDevice = await deviceController.createDongle(dongleId, 0, imei1, serial, publicKey);
2022-01-07 18:35:55 -07:00
2022-03-23 17:55:01 -06:00
logger.info('HTTP.V2.PILOTAUTH REGISTERED NEW DEVICE:', { newDevice, registerToken });
return res.status(201).json({
dongle_id: newDevice.dongle_id,
access_token: 'DEPRECATED-BUT-REQUIRED-FOR-07',
});
}
2022-01-08 17:57:15 -07:00
}
2022-03-22 09:14:08 -06:00
await deviceController.updateDevice(device.dongle_id, {
last_ping: Date.now(),
public_key: publicKey,
});
2022-01-08 17:57:15 -07:00
logger.info(`HTTP.V2.PILOTAUTH REACTIVATING KNOWN DEVICE (${imei1}, ${serial}) with dongle_id ${device.dongle_id}`);
2022-03-22 09:14:08 -06:00
return res.status(200).json({
dongle_id: device.dongle_id,
access_token: 'DEPRECATED-BUT-REQUIRED-FOR-07',
});
2022-01-07 18:35:55 -07:00
});
2022-01-07 18:35:55 -07:00
// RETRIEVES DATASET FOR OUR MODIFIED CABANA - THIS RESPONSE IS USED TO FAKE A DEMO ROUTE
router.get('/useradmin/cabana_drive/:extendedRouteIdentifier', runAsyncWrapper(async (req, res) => {
2022-03-23 17:55:01 -06:00
const { extendedRouteIdentifier } = req.params;
const [dongleId, dongleIdHashReq, driveIdentifier, driveIdentifierHashReq] = extendedRouteIdentifier.split('|');
2022-01-07 18:35:55 -07:00
2022-03-24 17:34:13 -06:00
const drive = await deviceController.getDriveFromIdentifier(dongleId, driveIdentifier);
2022-01-07 18:35:55 -07:00
if (!drive) {
2022-03-23 17:55:01 -06:00
return res.status(404).json({ status: 'drive not found' });
2022-01-07 18:35:55 -07:00
}
2022-03-24 17:36:42 -06:00
const dongleIdHash = crypto
.createHmac('sha256', process.env.APP_SALT)
.update(drive.dongle_id)
.digest('hex');
const driveIdentifierHash = crypto
.createHmac('sha256', process.env.APP_SALT)
.update(drive.identifier)
.digest('hex');
2022-03-24 16:05:05 -06:00
const driveUrl = `${process.env.BASE_DRIVE_DOWNLOAD_URL + dongleId}/${dongleIdHash}/${driveIdentifierHash}/${driveIdentifier}`;
2022-01-08 16:07:09 -07:00
if (dongleIdHash !== dongleIdHashReq || driveIdentifierHash !== driveIdentifierHashReq) {
2022-03-23 17:55:01 -06:00
return res.status(400).json({ status: 'hashes not matching' });
2022-01-07 18:35:55 -07:00
}
if (!drive.is_processed) {
2022-03-23 17:55:01 -06:00
return res.status(202).json({ status: 'drive is not processed yet' });
2022-01-07 18:35:55 -07:00
}
2022-01-08 15:00:08 -07:00
const logUrls = [];
for (let i = 0; i <= drive.max_segment; i++) {
2022-01-07 18:35:55 -07:00
logUrls.push(`${driveUrl}/${i}/rlog.bz2`);
}
2022-01-08 17:57:15 -07:00
return res.status(200).json({
2022-01-07 18:35:55 -07:00
logUrls,
driveUrl,
2022-03-24 16:05:05 -06:00
name: `${dongleId}|${driveIdentifier}`,
driveIdentifier,
dongleId,
2022-01-07 18:35:55 -07:00
});
}));
2022-01-12 08:02:30 -07:00
export default router;