From c835b4ca9836af9e7187966db7a379a4329c5384 Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 15:47:57 -0700 Subject: [PATCH 1/9] Add screenshot upload support --- .gitignore | 6 +- package-lock.json | 124 ++++++++++++++++++++++++++++++++++++- package.json | 1 + src/index.js | 45 +++++++++++++- src/migrator.js | 15 +++-- src/models/config.js | 12 ++-- src/views/devices.mustache | 6 +- src/views/header.mustache | 2 +- static/img/offline.png | Bin 0 -> 302 bytes static/img/online.png | Bin 0 -> 307 bytes 10 files changed, 186 insertions(+), 25 deletions(-) create mode 100644 static/img/offline.png create mode 100644 static/img/online.png diff --git a/.gitignore b/.gitignore index e5a549c..997428b 100644 --- a/.gitignore +++ b/.gitignore @@ -106,4 +106,8 @@ dist # No main configs config.json -logs \ No newline at end of file +# No logs +logs + +# No screenshots +screenshots \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 02cb538..ef5d837 100644 --- a/package-lock.json +++ b/package-lock.json @@ -101,6 +101,11 @@ "color-convert": "^1.9.0" } }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -164,6 +169,43 @@ "concat-map": "0.0.1" } }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -228,6 +270,17 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -301,6 +354,38 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -944,14 +1029,12 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, "requires": { "minimist": "^1.2.5" } @@ -961,6 +1044,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multer": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", + "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", + "requires": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + } + }, "mustache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.0.1.tgz", @@ -1017,6 +1115,11 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -1325,6 +1428,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -1480,6 +1588,11 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1545,6 +1658,11 @@ "mkdirp": "^0.5.1" } }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index 0504d66..48ff89c 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "license": "ISC", "dependencies": { "express": "^4.17.1", + "multer": "^1.4.2", "mustache": "^4.0.1", "mustache-express": "^1.3.0", "mysql": "^2.18.1" diff --git a/src/index.js b/src/index.js index c45b7b8..4d24145 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,8 @@ 'use strict'; +const multer = require('multer'); +const upload = multer({ dest: '../screenshots' }); +const fs = require('fs'); const path = require('path'); const express = require('express'); const bodyParser = require('body-parser'); @@ -27,6 +30,7 @@ app.set('views', path.resolve(__dirname, 'views')); app.engine('mustache', mustacheExpress()); app.use(bodyParser.urlencoded({ extended: false, limit: '50mb' })); // for parsing application/x-www-form-urlencoded app.use(express.static(path.resolve(__dirname, '../static'))); +app.use('/screenshots', express.static(path.resolve(__dirname, '../screenshots'))); const defaultData = { title: config.title, @@ -145,9 +149,13 @@ app.get('/api/devices', async function(req, res) { try { var devices = await Device.getAll(); devices.forEach(function(device) { + var screenshot = `/screenshots/${device.uuid}.png`; + var exists = fs.existsSync(path.join(__dirname, `..${screenshot}`)); + var image = exists ? screenshot : `/img/offline.png`; + device.image = ``; device.last_seen = utils.getDateTime(device.last_seen); device.buttons = ` - + `; }); var json = JSON.stringify({ data: { devices: devices } }); @@ -168,6 +176,37 @@ app.post('/api/device/new', async function(req, res) { res.redirect('/devices'); }); +app.post('/api/device/:uuid/screen', upload.single('file'), function(req, res) { + var uuid = req.params.uuid; + var fileName = uuid + '.png'; + const tempPath = req.file.path; + const screenshotsDir = path.resolve(__dirname, '../screenshots'); + const targetPath = path.join(screenshotsDir, fileName); + if (!fs.existsSync(screenshotsDir)) { + fs.mkdirSync(screenshotsDir); + } + //console.log("File:", req.file); + //console.log("Temp Path:", tempPath, "Target Path:", targetPath, "Original FileName:", req.file.originalname); + if (path.extname(req.file.originalname).toLowerCase() === '.png' || + path.extname(req.file.originalname).toLowerCase() === '.jpg' || + path.extname(req.file.originalname).toLowerCase() === '.jpeg') { + console.log("Moving file"); + fs.rename(tempPath, targetPath, function(err) { + if (err) return handleError(err, res); + res.status(200) + .contentType('text/plain') + .end('OK'); + }); + } else { + fs.unlink(tmepPath, function(err) { + if (err) return handleError(err, res); + res.status(200) + .contentType('text/plain') + .end('ERROR'); + }) + } +}); + app.post('/api/device/delete/:uuid', async function(req, res) { var uuid = req.params.uuid; var result = await Device.delete(uuid); @@ -380,7 +419,9 @@ app.post('/api/config/edit/:name', async function(req, res) { c.isDefault = data.is_default === 'on' ? 1 : 0; if (await c.save(oldName)) { // Success - if (c.isDefault !== false) { + console.log("IsDefault:", c.isDefault); + if (c.isDefault) { + console.log("Setting default for", oldName); await Config.setDefault(oldName); } } diff --git a/src/migrator.js b/src/migrator.js index 50de00f..427c24f 100644 --- a/src/migrator.js +++ b/src/migrator.js @@ -18,10 +18,10 @@ class Migrator { if (query === undefined || query === null) { var message = `Failed to connect to database (as root) while initializing. Try: ${count}/10`; if (count === 10) { - console.error('[DBController] ' + message); + console.error('[DBController]', message); process.exit(-1); } else { - console.error('[DBController] ' + message); + console.error('[DBController]', message); } count++; await utils.snooze(2500); @@ -39,7 +39,7 @@ class Migrator { await query(createMetadataTableSQL) .then(x => x) .catch(err => { - console.error('[DBController] Failed to create metadata table: (' + err + ')'); + console.error(`[DBController] Failed to create metadata table: (${err})`); process.exit(-1); }); @@ -51,7 +51,7 @@ class Migrator { var results = await query(getDBVersionSQL) .then(x => x) .catch(err => { - console.error('[DBController] Failed to get current database version: (' + err + ')'); + console.error(`[DBController] Failed to get current database version: (${err})`); process.exit(-1); }); if (results.length > 0) { @@ -71,17 +71,16 @@ class Migrator { } async migrate(fromVersion, toVersion) { if (fromVersion < toVersion) { - // TODO: Wait 30 seconds and let user know we are about to migrate the database and for them to make a backup until we handle backups and rollbacks. console.log('[DBController] MIGRATION IS ABOUT TO START IN 30 SECONDS, PLEASE MAKE SURE YOU HAVE A BACKUP!!!'); await utils.snooze(30 * 1000); - console.log('[DBController] Migrating database to version ' + (fromVersion + 1)); + console.log(`[DBController] Migrating database to version ${(fromVersion + 1)}`); var migrateSQL; try { var sqlFile = `${migrationsDir}${path.sep}${fromVersion + 1}.sql`; migrateSQL = utils.readFile(sqlFile); migrateSQL.replace('\r', '').replace('\n', ''); } catch (err) { - console.error('[DBController] Migration failed: ' + err); + console.error('[DBController] Migration failed:', err); process.exit(-1); } /* @@ -119,7 +118,7 @@ class Migrator { await query(updateVersionSQL) .then(x => x) .catch(err => { - console.error('[DBController] Migration failed: ' + err); + console.error('[DBController] Migration failed:', err); process.exit(-1); }); console.log('[DBController] Migration successful'); diff --git a/src/models/config.js b/src/models/config.js index 7b66432..0c6c79b 100644 --- a/src/models/config.js +++ b/src/models/config.js @@ -152,16 +152,12 @@ class Config { return data; } static async setDefault(name) { - // TODO: Update both in one sql statement - var sql = 'UPDATE configs SET is_default = 0 WHERE name != ?'; + var sql = ` + UPDATE dcm.configs + SET is_default = IF(name = ?, 1, 0);`; var args = [name]; var result = await query(sql, args); - if (result.affectedRows > 0) { - // Success - } - sql = 'UPDATE config SET is_default = 1 WHERE name = ?'; - result = await query(sql, args); - return result.affectedRows === 1; + return result.affectedRows > 0; } async save(oldName) { var sql = ` diff --git a/src/views/devices.mustache b/src/views/devices.mustache index f99242a..601a281 100644 --- a/src/views/devices.mustache +++ b/src/views/devices.mustache @@ -11,6 +11,7 @@ + @@ -40,16 +41,17 @@ "paging": true, "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], "columns": [ + { "data": "image" }, { "data": "uuid" }, { "data": "config" }, { "data": "last_seen" }, { "data": "buttons" }, ], "info": true, - "order": [[ 0, "asc" ]], + "order": [[ 1, "asc" ]], "search.caseInsensitive": true, "columnDefs": [ { - "targets": [3], + "targets": [4], "orderable": false }], "responsive": true diff --git a/src/views/header.mustache b/src/views/header.mustache index 1d53f09..3ad28a8 100644 --- a/src/views/header.mustache +++ b/src/views/header.mustache @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/static/img/offline.png b/static/img/offline.png new file mode 100644 index 0000000000000000000000000000000000000000..561dcced9cf69e772c72a291a1595de1d741e8f9 GIT binary patch literal 302 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sApt%iuI>dsKqiskxsS~`7t^!O zrji`&Qk?8gVuDM}w3nG{Z?e|gXr<>OCUoA#%u!Tuc6i-npox4XL4LsuYd^?*R9U(D z?I-CsYN|hH7;ON`RC~HOhIkx*du=;kg8>gqfR{o`(X#9R|NEa}&`7wUd_V2wy_#<} z*M+i}wU6oB{o;(9v_$8^j5MkDPa98(8FKS@DXm&xw|TB8lNdvEi?#=iggxi?6@T|EE* literal 0 HcmV?d00001 diff --git a/static/img/online.png b/static/img/online.png new file mode 100644 index 0000000000000000000000000000000000000000..da811fed3687fdc29d9a3b586f85ae1a3fbe076a GIT binary patch literal 307 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sfdM`tuI>dsKqiqu?@XcQwp3m# z1YYjv*e$-(EW@-X6|Bb5>u4a8U6a|zbZf53R7@Imr| z((o$I7k8%0ROkx4UJ$WUT15VtiWl?ACY#+dM?2W%dQM2|ftj_mA O{`PeBb6Mw<&;$U<*Iv8; literal 0 HcmV?d00001 From 5f4af011b2e4ca8cde420c511f55e9c1092919f8 Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 17:01:12 -0700 Subject: [PATCH 2/9] Check for undefined x-forwarded-for header --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 417d4ac..5662e93 100644 --- a/src/index.js +++ b/src/index.js @@ -225,7 +225,7 @@ app.get('/api/config/:uuid', async function(req, res) { var device = await Device.getByName(uuid); var noConfig = false; // Check for a proxied IP before the normal IP and set the first one at exists - var clientip = (req.headers['x-forwarded-for'].split(', ')[0]) || (req.connection.remoteAddress).match("[0-9]+.[0-9].+[0-9]+.[0-9]+$")[0]; + var clientip = ((req.headers['x-forwarded-for'] || '').split(', ')[0]) || (req.connection.remoteAddress).match("[0-9]+.[0-9].+[0-9]+.[0-9]+$")[0]; // Check if device config is empty, if not provide it as json response if (device) { From bc13998ecc52c88eea73eca5057efc4192bad0a7 Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 17:03:49 -0700 Subject: [PATCH 3/9] Linting --- src/index.js | 8 ++++---- src/migrator.js | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/index.js b/src/index.js index 5662e93..a88176e 100644 --- a/src/index.js +++ b/src/index.js @@ -78,16 +78,16 @@ app.get('/device/manage/:uuid', async function(req, res) { if (device.config) { var c = await Config.getByName(device.config); if (c === null) { - console.error("Failed to grab config", device.config); + console.error('Failed to grab config', device.config); return; } else { data.port = c.port; } } if (device.clientip === null) { - console.error("Failed to get IP address."); + console.error('Failed to get IP address.'); } else { - data.clientip = device.clientip + data.clientip = device.clientip; } } res.render('device-manage', data); @@ -225,7 +225,7 @@ app.get('/api/config/:uuid', async function(req, res) { var device = await Device.getByName(uuid); var noConfig = false; // Check for a proxied IP before the normal IP and set the first one at exists - var clientip = ((req.headers['x-forwarded-for'] || '').split(', ')[0]) || (req.connection.remoteAddress).match("[0-9]+.[0-9].+[0-9]+.[0-9]+$")[0]; + var clientip = ((req.headers['x-forwarded-for'] || '').split(', ')[0]) || (req.connection.remoteAddress).match('[0-9]+.[0-9].+[0-9]+.[0-9]+$')[0]; // Check if device config is empty, if not provide it as json response if (device) { diff --git a/src/migrator.js b/src/migrator.js index 50de00f..3dc0074 100644 --- a/src/migrator.js +++ b/src/migrator.js @@ -71,7 +71,7 @@ class Migrator { } async migrate(fromVersion, toVersion) { if (fromVersion < toVersion) { - // TODO: Wait 30 seconds and let user know we are about to migrate the database and for them to make a backup until we handle backups and rollbacks. + // Wait 30 seconds and let user know we are about to migrate the database and for them to make a backup until we handle backups and rollbacks. console.log('[DBController] MIGRATION IS ABOUT TO START IN 30 SECONDS, PLEASE MAKE SURE YOU HAVE A BACKUP!!!'); await utils.snooze(30 * 1000); console.log('[DBController] Migrating database to version ' + (fromVersion + 1)); @@ -84,7 +84,6 @@ class Migrator { console.error('[DBController] Migration failed: ' + err); process.exit(-1); } - /* var sqlSplit = migrateSQL.split(';'); sqlSplit.forEach(async sql => { let msql = sql.replace('&semi', ';').trim(); @@ -93,6 +92,7 @@ class Migrator { .then(x => x) .catch(async err => { console.error('[DBController] Migration failed: ' + err + '\r\nExecuting SQL statement: ' + msql); + /* if (noBackup === undefined || noBackup === null || noBackup === false) { for (let i = 0; i < 10; i++) { logger.warn(`[DBController] Rolling back migration in ${(10 - i)} seconds`); @@ -107,10 +107,10 @@ class Migrator { } //fatalError(message); return null; + */ }); } }); - */ var updateVersionSQL = ` INSERT INTO metadata (\`key\`, \`value\`) From 42aaebc534aa2040fdccb1c535a8c8e23785457b Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 17:08:57 -0700 Subject: [PATCH 4/9] Get account info, not send :P --- src/views/device-manage.mustache | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/views/device-manage.mustache b/src/views/device-manage.mustache index e3c303c..c765346 100644 --- a/src/views/device-manage.mustache +++ b/src/views/device-manage.mustache @@ -26,6 +26,10 @@ + + + + @@ -45,17 +49,6 @@ - - - - + + + + From 4e5b3f73bde3f733edbd104b77def90c2f8340ff Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 17:12:24 -0700 Subject: [PATCH 6/9] Add placeholders for send methods --- src/views/device-manage.mustache | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/device-manage.mustache b/src/views/device-manage.mustache index c9ce4db..acb50d9 100644 --- a/src/views/device-manage.mustache +++ b/src/views/device-manage.mustache @@ -58,7 +58,7 @@ + + + + From 8abbaeda9c8b93ebfce4a4ffcefc85d7adcb8895 Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 17:50:56 -0700 Subject: [PATCH 9/9] Update README.md --- README.md | 25 +++++++++++++++++++++---- src/index.js | 6 +++--- src/migrator.js | 3 +-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c503857..e646310 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,24 @@ To be used with RealDeviceMap macless solution Kevin. -1.) Install dependencies `npm install` -2.) Copy config `cp src/config.example.json src/config.json` -3.) Fill out `vi src/config.json` -4.) Run `npm run start` +Central repository for macless client configurations without having to keep track of multiple remote configs and urls. Assign different configurations to different devices and different backends (RealDeviceMap / Lorgnette). When devices connect for the first time, if they don't exist they are created, if they don't have a config assigned, it will try to auto-assign it a default config if one exists. +You can also pre-create devices and assign configs yourself if needed. +## Features +- Custom config assignments +- Screenshot preview +- Device logging +- Device endpoint tooling +- and more... + +## Installation +1.) Clone repository `git clone https://github.com/versx/DeviceConfigManager` +2.) Install dependencies `npm install` +3.) Copy config `cp src/config.example.json src/config.json` +4.) Fill out config `vi src/config.json` +5.) Run `npm run start` + +## PM2 (recommended) Once everything is setup and running appropriately, you can add this to PM2 ecosystem.config.js file so it is automatically started: ``` module.exports = { @@ -24,3 +37,7 @@ module.exports = { ] }; ``` + +## TODO +- Support for other macless client provider configs with custom predefined configuration keys. +- Localization. \ No newline at end of file diff --git a/src/index.js b/src/index.js index 83328e5..3b5d721 100644 --- a/src/index.js +++ b/src/index.js @@ -199,9 +199,9 @@ app.get('/api/devices', async function(req, res) { app.post('/api/device/new', async function(req, res) { var uuid = req.body.uuid; - var config = req.body.config; - var clientip = req.body.clientip; - var result = await Device.create(uuid, config, clientip || null, null, null); + var config = req.body.config || null; + var clientip = req.body.clientip || null; + var result = await Device.create(uuid, config, null, clientip); if (result) { // Success } diff --git a/src/migrator.js b/src/migrator.js index 587c496..182f7d1 100644 --- a/src/migrator.js +++ b/src/migrator.js @@ -3,10 +3,9 @@ const path = require('path'); const fs = require('fs'); const query = require('./db.js'); -const migrationsDir = path.resolve(__dirname, '../migrations'); const utils = require('./utils.js'); -// TODO: Load metadata table +const migrationsDir = path.resolve(__dirname, '../migrations'); class Migrator { constructor() {
Preview UUID Config Last Seen Get Current Config Data
Get Current Account Data
Restart Game
Send Account Info (WIP) -
-
- -
- -
-
Send Pixel Check Location (WIP) From d207bb675fdef2ac0b09873e958ea19f31b8ac70 Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 17:09:46 -0700 Subject: [PATCH 5/9] Add get system_info from device endpoint --- src/views/device-manage.mustache | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/views/device-manage.mustache b/src/views/device-manage.mustache index c765346..c9ce4db 100644 --- a/src/views/device-manage.mustache +++ b/src/views/device-manage.mustache @@ -30,6 +30,10 @@ Get Current Account Data
Get System Information Data
Restart Game
- +
@@ -69,7 +69,7 @@
- +
@@ -80,7 +80,7 @@
- +
From 7e0b6ea52dd87027d3891bb174c7eb51dd1ce573 Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 17:23:55 -0700 Subject: [PATCH 7/9] Use dropdown for device buttons --- src/index.js | 15 +++++++++++---- src/views/header.mustache | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/index.js b/src/index.js index a88176e..74b2264 100644 --- a/src/index.js +++ b/src/index.js @@ -170,10 +170,17 @@ app.get('/api/devices', async function(req, res) { var devices = await Device.getAll(); devices.forEach(function(device) { device.last_seen = utils.getDateTime(device.last_seen); - device.buttons = ` - - - `; + device.buttons = ` +
+ + +
`; }); var json = JSON.stringify({ data: { devices: devices } }); res.send(json); diff --git a/src/views/header.mustache b/src/views/header.mustache index 1d53f09..3ad28a8 100644 --- a/src/views/header.mustache +++ b/src/views/header.mustache @@ -8,7 +8,7 @@ - + \ No newline at end of file From b0b7cb32c3c4e8f7c6fdd846f530b08175377629 Mon Sep 17 00:00:00 2001 From: versx Date: Mon, 20 Apr 2020 17:34:38 -0700 Subject: [PATCH 8/9] Add get screenshot button --- src/index.js | 2 +- src/migrator.js | 9 +++++---- src/views/device-manage.mustache | 4 ++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/index.js b/src/index.js index 3923b61..83328e5 100644 --- a/src/index.js +++ b/src/index.js @@ -183,7 +183,7 @@ app.get('/api/devices', async function(req, res) {
Get Screenshot
Get Current Location