From 73454da76df311ecf8c92208cc3fcb041e2918e9 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Thu, 24 Mar 2022 21:03:19 +0000 Subject: [PATCH] refactor(useradmin): improve code formatting, remove duplicate code --- src/server/router/useradmin.js | 270 +++++++++++++++++---------------- 1 file changed, 138 insertions(+), 132 deletions(-) diff --git a/src/server/router/useradmin.js b/src/server/router/useradmin.js index 54fe625..9c598c0 100644 --- a/src/server/router/useradmin.js +++ b/src/server/router/useradmin.js @@ -7,15 +7,15 @@ import htmlspecialchars from 'htmlspecialchars'; import dirTree from 'directory-tree'; import cookieParser from 'cookie-parser'; import log4js from 'log4js'; + import authenticationController from '../controllers/authentication'; import helperController from '../controllers/helpers'; import mailingController from '../controllers/mailing'; import deviceController from '../controllers/devices'; import userController from '../controllers/users'; -import { getAccount, requireAuthenticated } from '../middlewares/authentication'; +import { getAccount } from '../middlewares/authentication'; -const logger = log4js.getLogger(); -let models; +const logger = log4js.getLogger('useradmin'); const router = express.Router(); // TODO Remove this, pending on removing all auth logic from routes router.use(cookieParser()); @@ -27,6 +27,16 @@ function runAsyncWrapper(callback) { }; } +const requireAuthenticated = async (req, res, next) => { + const account = await authenticationController.getAuthenticatedAccount(req); + if (account == null) { + return res.redirect(`/useradmin?status=${encodeURIComponent('Invalid or expired session')}`); + } else { + req.account = account; + return next(); + } +}; + if (process.env.NODE_ENV === 'development') { router.get('/createbaseaccount', runAsyncWrapper(async (req, res) => { res.send(await userController.createBaseAccount()); @@ -52,8 +62,8 @@ router.get('/signout', runAsyncWrapper(async (req, res) => { res.redirect(`/useradmin?status=${encodeURIComponent('Signed out')}`); })); -router.get('/', runAsyncWrapper(async (req, res) => { - const account = await authenticationController.getAuthenticatedAccount(req); +router.get('/', getAccount, runAsyncWrapper(async (req, res) => { + const { account } = req; if (account != null) { res.redirect('/useradmin/overview'); return; @@ -167,13 +177,12 @@ router.post('/register/token', bodyParser.urlencoded({ extended: true }), runAsy `); })); -router.get('/register', runAsyncWrapper(async (req, res) => { +router.get('/register', getAccount, runAsyncWrapper(async (req, res) => { if (!process.env.ALLOW_REGISTRATION) { - return res.status(400).send('Unauthorized.'); + return res.status(401).send('Unauthorized.'); } - const account = await authenticationController.getAuthenticatedAccount(req); - if (account != null) { + if (req.account) { return res.redirect('/useradmin/overview'); } @@ -190,14 +199,8 @@ router.get('/register', runAsyncWrapper(async (req, res) => { `); })); -router.get('/overview', runAsyncWrapper(async (req, res) => { - let account = await authenticationController.getAuthenticatedAccount(req); - if (account === null) { - return res.redirect(`/useradmin?status=${encodeURIComponent('Invalid or expired session')}`); - } - - account = account.dataValues; - +router.get('/overview', requireAuthenticated, runAsyncWrapper(async (req, res) => { + const { account } = req; const devices = await deviceController.getDevices(account.id); let response = ` @@ -243,21 +246,13 @@ ${req.query.linkstatus !== undefined ? `
${htmlspecialchars(req.query.link })); // TODO: move to useradmin api -router.get('/api/useradmin/unpair_device/:dongleId', runAsyncWrapper(async (req, res) => { - const account = await authenticationController.getAuthenticatedAccount(req); - if (account == null) { - return res.redirect(`/useradmin?status=${encodeURIComponent('Invalid or expired session')}`); - } - +router.get('/api/useradmin/unpair_device/:dongleId', requireAuthenticated, runAsyncWrapper(async (req, res) => { + // TODO: implement unpair_device? return res.redirect('/useradmin/overview'); })); -router.post('/pair_device', [getAccount, bodyParser.urlencoded({ extended: true })], runAsyncWrapper(async (req, res) => { +router.post('/pair_device', [requireAuthenticated, bodyParser.urlencoded({ extended: true })], runAsyncWrapper(async (req, res) => { const { account, body: { qrString } } = req; - if (!account) { - res.redirect(`/useradmin?status=${encodeURIComponent('Invalid or expired session')}`); - return; - } const pairDevice = await deviceController.pairDevice(account, qrString); if (pairDevice.success === true) { @@ -275,33 +270,30 @@ router.post('/pair_device', [getAccount, bodyParser.urlencoded({ extended: true } })); -router.get('/device/:dongleId', runAsyncWrapper(async (req, res) => { +router.get('/device/:dongleId', requireAuthenticated, runAsyncWrapper(async (req, res) => { const { dongleId } = req.params; - - const account = await authenticationController.getAuthenticatedAccount(req); - if (account == null) { - return res.redirect(`/useradmin?status=${encodeURIComponent('Invalid or expired session')}`); - } - const device = await deviceController.getDeviceFromDongleId(dongleId); if (!device) { return res.status(404).send('Not Found.'); - } else if (device.account_id !== account.id) { + } + + const { account_id: accountId } = device; + if (accountId !== req.account.id) { return res.status(401).send('Unauthorized.'); } - const drives = await deviceController.getDrives(device.dongle_id, false, true); + const drives = await deviceController.getDrives(dongleId, false, true); - const dongleIdHash = crypto.createHmac('sha256', process.env.APP_SALT).update(device.dongle_id).digest('hex'); + const dongleIdHash = crypto.createHmac('sha256', process.env.APP_SALT).update(dongleId).digest('hex'); - const bootlogFiles = await deviceController.getBootlogs(device.dongle_id); - const crashlogFiles = await deviceController.getCrashlogs(device.dongle_id); + const bootlogFiles = await deviceController.getBootlogs(dongleId); + const crashlogFiles = await deviceController.getCrashlogs(dongleId); let response = `

Welcome To The RetroPilot Server Dashboard!

< < < Back To Overview

-

Device ${device.dongle_id}

+

Device ${dongleId}

Type: ${device.device_type}
Serial: ${device.serial}
IMEI: ${device.imei}
@@ -319,7 +311,7 @@ router.get('/device/:dongleId', runAsyncWrapper(async (req, res) => { datefilesize `; for (let i = 0; i < Math.min(5, bootlogFiles.length); i++) { - response += `${helperController.formatDate(bootlogFiles[i].date)}${bootlogFiles[i].name}${bootlogFiles[i].size}`; + response += `${helperController.formatDate(bootlogFiles[i].date)}${bootlogFiles[i].name}${bootlogFiles[i].size}`; } response += '

'; @@ -329,7 +321,7 @@ router.get('/device/:dongleId', runAsyncWrapper(async (req, res) => { for (let i = 0; i < Math.min(5, crashlogFiles.length); i++) { response += ` ${helperController.formatDate(crashlogFiles[i].date)}. - ${crashlogFiles[i].name} + ${crashlogFiles[i].name} ${crashlogFiles[i].size} `; } @@ -373,7 +365,7 @@ router.get('/device/:dongleId', runAsyncWrapper(async (req, res) => { } response += ` - ${drive.is_preserved ? '' : ''}${drive.identifier}${drive.is_preserved ? '' : ''} + ${drive.is_preserved ? '' : ''}${drive.identifier}${drive.is_preserved ? '' : ''} ${vehicle} ${version} ${Math.round(drive.filesize / 1024)} MiB @@ -383,8 +375,8 @@ router.get('/device/:dongleId', runAsyncWrapper(async (req, res) => { ${drive.is_processed} ${helperController.formatDate(drive.created)} - [delete] - ${drive.is_preserved ? '' : `[preserve]`} + [delete] + ${drive.is_preserved ? '' : `[preserve]`} `; }); @@ -392,7 +384,7 @@ router.get('/device/:dongleId', runAsyncWrapper(async (req, res) => { response += `

- Unpair Device + Unpair Device


Sign Out @@ -401,58 +393,38 @@ router.get('/device/:dongleId', runAsyncWrapper(async (req, res) => { return res.status(200).send(response); })); -// TODO: move to user admin api? -router.get('/drive/:dongleId/:driveIdentifier/:action', runAsyncWrapper(async (req, res) => { - const account = await authenticationController.getAuthenticatedAccount(req); - if (account == null) { - return res.redirect(`/useradmin?status=${encodeURIComponent('Invalid or expired session')}`); - } - - const drive = await deviceController.getDrive(req.params.dongleId, req.params.driveIdentifier); - if (drive == null) { - return res.status(404).send('Not Found.'); - } - - const { action } = req.params; - if (action === 'delete') { - await deviceController.updateOrCreateDrive(req.params.dongleId, drive.id, { - is_deleted: true, - }); - } else if (action === 'preserve') { - await deviceController.updateOrCreateDrive(req.params.dongleId, drive.id, { - is_preserved: true, - }); - } - - return res.redirect(`/useradmin/device/${device.dongle_id}`); -})); - -router.get('/drive/:dongleId/:driveIdentifier', runAsyncWrapper(async (req, res) => { - const account = await authenticationController.getAuthenticatedAccount(req); - if (account == null) { - return res.redirect(`/useradmin?status=${encodeURIComponent('Invalid or expired session')}`); - } - - const device = await deviceController.getDeviceFromDongleId(req.params.dongleId); +router.get('/drive/:dongleId/:driveIdentifier', requireAuthenticated, runAsyncWrapper(async (req, res) => { + const { dongleId } = req.params; + const device = await deviceController.getDeviceFromDongleId(dongleId); if (!device) { return res.status(404).send('Not Found.'); - } else if (device.account_id !== account.id) { - return res.status(401).send('Unauthorized.'); } - const drive = await deviceController.getDrive(req.params.dongleId, req.params.driveIdentifier); + const { account_id: accountId } = device; + if (accountId !== req.account.id) { + return res.status(403).send('Forbidden.'); + } + + const { driveIdentifier } = req.params; + const drive = await deviceController.getDrive(dongleId, driveIdentifier); if (drive == null) { return res.status(404).send('Not Found.'); } - const dongleIdHash = crypto.createHmac('sha256', process.env.APP_SALT).update(device.dongle_id).digest('hex'); - const driveIdentifierHash = crypto.createHmac('sha256', process.env.APP_SALT).update(drive.identifier).digest('hex'); + const dongleIdHash = crypto + .createHmac('sha256', process.env.APP_SALT) + .update(dongleId) + .digest('hex'); + const driveIdentifierHash = crypto + .createHmac('sha256', process.env.APP_SALT) + .update(driveIdentifier) + .digest('hex'); - const driveUrl = `${process.env.BASE_DRIVE_DOWNLOAD_URL + device.dongle_id}/${dongleIdHash}/${driveIdentifierHash}/${drive.identifier}/`; + const driveUrl = `${process.env.BASE_DRIVE_DOWNLOAD_URL + dongleId}/${dongleIdHash}/${driveIdentifierHash}/${driveIdentifier}/`; let cabanaUrl = null; if (drive.is_processed) { - cabanaUrl = `${process.env.CABANA_URL}?retropilotIdentifier=${device.dongle_id}|${dongleIdHash}|${drive.identifier}|${driveIdentifierHash}&retropilotHost=${encodeURIComponent(process.env.BASE_URL)}&demo=1"`; + cabanaUrl = `${process.env.CABANA_URL}?retropilotIdentifier=${dongleId}|${dongleIdHash}|${driveIdentifier}|${driveIdentifierHash}&retropilotHost=${encodeURIComponent(process.env.BASE_URL)}&demo=1"`; } let vehicle = ''; @@ -507,15 +479,15 @@ router.get('/drive/:dongleId/:driveIdentifier', runAsyncWrapper(async (req, res)

Welcome To The RetroPilot Server Dashboard!

- < < < Back To Device ${device.dongle_id} -

Drive ${drive.identifier} on ${drive.dongle_id}

+ < < < Back To Device ${dongleId} +

Drive ${driveIdentifier} on ${dongleId}

Drive Date: ${helperController.formatDate(drive.drive_date)}
Upload Date: ${helperController.formatDate(drive.created)}

Vehicle: ${vehicle}
Openpilot Version: ${version}

- GIT Remote: ${gitRemote}
- GIT Branch: ${gitBranch}
- GIT Commit: ${gitCommit}

+ Git Remote: ${gitRemote}
+ Git Branch: ${gitBranch}
+ Git Commit: ${gitCommit}

Num Segments: ${drive.max_segment + 1}
Storage: ${Math.round(drive.filesize / 1024)} MiB
Duration: ${helperController.formatDuration(drive.duration)}
@@ -595,64 +567,98 @@ router.get('/drive/:dongleId/:driveIdentifier', runAsyncWrapper(async (req, res) `; - const directoryTree = dirTree(process.env.STORAGE_PATH + device.dongle_id + "/" + dongleIdHash + "/" + driveIdentifierHash + "/" + drive.identifier); + const directoryTree = dirTree(`${process.env.STORAGE_PATH + dongleId}/${dongleIdHash}/${driveIdentifierHash}/${driveIdentifier}`); const directorySegments = {}; - for (var i in directoryTree.children) { + await Promise.all(directoryTree.children.map(async (directory) => { // skip any non-directory entries (for example m3u8 file in the drive directory) - if (directoryTree.children[i].type != 'directory') continue; + if (directory.type !== 'directory') return; - var segment = directoryTree.children[i].name; + const segment = directory.name; - - var qcamera = '--'; - var fcamera = '--'; - var dcamera = '--'; - var qlog = '--'; - var rlog = '--'; - for (var c in directoryTree.children[i].children) { - if (directoryTree.children[i].children[c].name == 'fcamera.hevc') fcamera = '' + driveUrl + segment + '' + directoryTree.children[i].children[c].name + '' + directoryTree.children[i].children[c].name + ''; - if (directoryTree.children[i].children[c].name == 'dcamera.hevc') fcamera = '' + driveUrl + segment + '' + directoryTree.children[i].children[c].name + '' + directoryTree.children[i].children[c].name + ''; - if (directoryTree.children[i].children[c].name == 'qcamera.ts') qcamera = '' + driveUrl + segment + '' + directoryTree.children[i].children[c].name + '' + directoryTree.children[i].children[c].name + ''; - if (directoryTree.children[i].children[c].name == 'qlog.bz2') qlog = '' + driveUrl + segment + '' + directoryTree.children[i].children[c].name + '' + directoryTree.children[i].children[c].name + ''; - if (directoryTree.children[i].children[c].name == 'rlog.bz2') rlog = '' + driveUrl + segment + '' + directoryTree.children[i].children[c].name + '' + directoryTree.children[i].children[c].name + ''; - } + let fcamera = '--'; + let dcamera = '--'; + let qcamera = '--'; + let qlog = '--'; + let rlog = '--'; + directory.children.forEach((file) => { + if (file.name === 'fcamera.hevc') fcamera = `${driveUrl}${segment}${file.name}`; + if (file.name === 'dcamera.hevc') dcamera = `${driveUrl}${segment}${file.name}`; + if (file.name === 'qcamera.ts') qcamera = `${driveUrl}${segment}${file.name}`; + if (file.name === 'qlog.bz2') qlog = `${driveUrl}${segment}${file.name}`; + if (file.name === 'rlog.bz2') rlog = `${driveUrl}${segment}${file.name}`; + }) let isProcessed = '?'; let isStalled = '?'; - const drive_segment = await models.__db.get('SELECT * FROM drive_segments WHERE segment_id = ? AND drive_identifier = ? AND dongle_id = ?', parseInt(segment), drive.identifier, device.dongle_id); + const driveSegment = await DriveSegments.findOne({ + where: { + segment_id: parseInt(segment, 10), + drive_identifier: drive.identifier, + dongle_id: device.dongle_id + }, + }); - if (drive_segment) { - isProcessed = drive_segment.is_processed; - isStalled = drive_segment.is_stalled; + if (driveSegment) { + isProcessed = driveSegment.is_processed; + isStalled = driveSegment.is_stalled; } - directorySegments["seg-" + segment] = ''; -} + directorySegments[`seg-${segment}`] = ``; + })); -var qcamera = '--'; -var fcamera = '--'; -var dcamera = '--'; -var qlog = '--'; -var rlog = '--'; -var isProcessed = '?'; -var isStalled = '?'; + let qcamera = '--'; + let fcamera = '--'; + let dcamera = '--'; + let qlog = '--'; + let rlog = '--'; + let isProcessed = '?'; + let isStalled = '?'; -for (var i = 0; i <= drive.max_segment; i++) { - if (directorySegments["seg-" + i] == undefined) { - response += ''; - } else - response += directorySegments["seg-" + i]; -} + for (let i = 0; i <= drive.max_segment; i++) { + if (!directorySegments[`seg-${i}`]) { + response += ``; + } else { + response += directorySegments[`seg-${i}`]; + } + } -response += `
segmentqcameraqlogfcamerarlogdcameraprocessedstalled
' + segment + '' + qcamera + '' + qlog + '' + fcamera + '' + rlog + '' + dcamera + '' + isProcessed + '' + isStalled + '
${segment}${qcamera}${qlog}${fcamera}${rlog}${dcamera}${isProcessed}${isStalled}
' + i + '' + qcamera + '' + qlog + '' + fcamera + '' + rlog + '' + dcamera + '' + isProcessed + '' + isStalled + '
${i}${qcamera}${qlog}${fcamera}${rlog}${dcamera}${isProcessed}${isStalled}
+ response += `


Sign Out`; -res.status(200); -res.send(response); - + return res.status(200).send(response); })) +// TODO: move to user admin api? +router.get('/drive/:dongleId/:driveIdentifier/:action', requireAuthenticated, runAsyncWrapper(async (req, res) => { + const { + dongleId, + driveIdentifier, + } = req.params; + const drive = await deviceController.getDrive(dongleId, driveIdentifier); + if (!drive) { + return res.status(404).send('Not Found.'); + } + + const { account_id: accountId } = drive; + if (accountId !== req.account.id) { + return res.status(403).send('Forbidden.'); + } + + const { action } = req.params; + if (action === 'delete') { + await deviceController.updateOrCreateDrive(dongleId, driveIdentifier, { + is_deleted: true, + }); + } else if (action === 'preserve') { + await deviceController.updateOrCreateDrive(dongleId, driveIdentifier, { + is_preserved: true, + }); + } + + return res.redirect(`/useradmin/device/${dongleId}`); +})); + export default router;