Skip to content

Commit

Permalink
Merge pull request #7 from Kneckter/patch-4
Browse files Browse the repository at this point in the history
Device Management Page and Device IP Tracking
  • Loading branch information
versx authored Apr 20, 2020
2 parents f489e36 + f798147 commit 9b42975
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = {
{
name: 'DeviceConfigManager',
script: 'index.js',
cwd: '/home/username/DeviceConfigManager/',
cwd: '/home/username/DeviceConfigManager/src/',
instances: 1,
autorestart: true,
watch: false,
Expand Down
1 change: 1 addition & 0 deletions migrations/2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE `devices` ADD COLUMN IF NOT EXISTS `clientip` VARCHAR(40) DEFAULT NULL;
36 changes: 33 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,30 @@ app.get('/device/delete/:uuid', async function(req, res) {
res.render('device-delete', defaultData);
});

app.get('/device/manage/:uuid', async function(req, res) {
var uuid = req.params.uuid;
var device = await Device.getByName(uuid);
var data = defaultData;
data.name = uuid;
if (device) {
if (device.config) {
var c = await Config.getByName(device.config);
if (c === null) {
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.");
} else {
data.clientip = device.clientip
}
}
res.render('device-manage', data);
});

app.get('/configs', function(req, res) {
res.render('configs', defaultData);
});
Expand Down Expand Up @@ -148,7 +172,8 @@ app.get('/api/devices', async function(req, res) {
device.last_seen = utils.getDateTime(device.last_seen);
device.buttons = `<a href='/config/assign/${device.uuid}'><button type='button' class='btn btn-primary'>Assign</button></a>
<a href='/device/logs/${device.uuid}'><button type='button' class='btn btn-info'>Logs</button></a>
<a href='/device/delete/${device.uuid}'><button type='button' class='btn btn-danger'>Delete</button></a>`;
<a href='/device/delete/${device.uuid}'><button type='button' class='btn btn-danger'>Delete</button></a>
<a href='/device/manage/${device.uuid}'><button type='button' class='btn btn-success'>Manager</button></a>`;
});
var json = JSON.stringify({ data: { devices: devices } });
res.send(json);
Expand All @@ -160,7 +185,8 @@ 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 result = await Device.create(uuid, config || null, null);
var clientip = req.body.clientip;
var result = await Device.create(uuid, config, clientip || null, null, null);
if (result) {
// Success
}
Expand Down Expand Up @@ -198,10 +224,14 @@ app.get('/api/config/:uuid', async function(req, res) {
var uuid = req.params.uuid;
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];

// Check if device config is empty, if not provide it as json response
if (device) {
// Device exists
device.lastSeen = new Date() / 1000;
device.clientip = clientip;
device.save();
if (device.config) {
// Do something
Expand All @@ -221,7 +251,7 @@ app.get('/api/config/:uuid', async function(req, res) {
} else {
console.log('Device does not exist, creating...');
// Device doesn't exist, create db entry
var result = await Device.create(uuid); // REVIEW: Maybe return Device object upon creation to prevent another sql call to get Device object?
var result = await Device.create(uuid, clientip); // REVIEW: Maybe return Device object upon creation to prevent another sql call to get Device object?
if (result) {
// Success, assign default config if there is one.
var defaultConfig = await Config.getDefault();
Expand Down
22 changes: 12 additions & 10 deletions src/models/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
const query = require('../db.js');

class Device {
constructor(uuid, config, lastSeen) {
constructor(uuid, config, lastSeen, clientip) {
this.uuid = uuid;
this.config = config;
this.lastSeen = lastSeen;
this.clientip = clientip;
}
static async getAll() {
var devices = await query('SELECT uuid, config, last_seen FROM devices');
var devices = await query('SELECT uuid, config, last_seen, clientip FROM devices');
return devices;
}
static async getByName(uuid) {
var sql = `
SELECT uuid, config, last_seen
SELECT uuid, config, last_seen, clientip
FROM devices
WHERE uuid = ?`;
var args = [uuid];
Expand All @@ -25,14 +26,15 @@ class Device {
return new Device(
result[0].uuid,
result[0].config,
result[0].last_seen
result[0].last_seen,
result[0].clientip
);
}
static async create(uuid, config = null, lastSeen = null) {
static async create(uuid, config = null, lastSeen = null, clientip) {
var sql = `
INSERT INTO devices (uuid, config, last_seen)
VALUES (?, ?, ?)`;
var args = [uuid, config, lastSeen];
INSERT INTO devices (uuid, config, last_seen, clientip)
VALUES (?, ?, ?, ?)`;
var args = [uuid, config, lastSeen, clientip];
var result = await query(sql, args);
return result.affectedRows === 1;
}
Expand All @@ -45,9 +47,9 @@ class Device {
async save() {
var sql = `
UPDATE devices
SET config = ?, last_seen = ?
SET config = ?, last_seen = ?, clientip = ?
WHERE uuid = ?`;
var args = [this.config, this.lastSeen, this.uuid];
var args = [this.config, this.lastSeen, this.clientip, this.uuid];
var result = await query(sql, args);
return result.affectedRows === 1;
}
Expand Down
104 changes: 104 additions & 0 deletions src/views/device-manage.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<!DOCTYPE html="{{locale}}">
{{> header}}
<body>
{{> navbar}}
<br>
<h1 align="center" id="header">{{name}} Management</h1>
<br>
<div class="w-75" style="float: none; margin: 0 auto;">
<table id="table" class="table table-{{style}} table-striped table-bordered table-hover dt-responsive nowrap" style="position: center; width:100%">
<thead class="thead-dark">
<tr>
<th width="40%">Description</th>
<th width="40%"></th>
</tr>
</thead>
<tbody>
<tr>
<th>Get Current Location</th>
<th><a href='http://{{clientip}}:{{port}}/loc'><button type='button' class='btn btn-success'>GET</button></a></th>
</tr>
<tr>
<th>Clear Current Config</th>
<th><a href='http://{{clientip}}:{{port}}/clear'><button type='button' class='btn btn-danger'>CLEAR</button></a></th>
</tr>
<tr>
<th>Get Current Config Data</th>
<th><a href='http://{{clientip}}:{{port}}/config'><button type='button' class='btn btn-success'>GET</button></a></th>
</tr>
<tr>
<th>Restart Game</th>
<th><a href='http://{{clientip}}:{{port}}/restart'><button type='button' class='btn btn-danger'>RESTART</button></a></th>
</tr>
<tr>
<th>Reboot Device (WIP currently restarts the game)</th>
<th><a href='http://{{clientip}}:{{port}}/reboot'><button type='button' class='btn btn-danger'>REBOOT</button></a></th>
</tr>
<tr>
<th>Send Data for Testing (WIP)</th>
<th>
<form action="http://{{clientip}}:{{port}}/data" method="post">
<div class="form-group">
<input type="text" class="form-control" name="data_text" placeholder="{}">
</div>
<button type='submit' class='btn btn-danger'>SEND</button>
</form>
</th>
</tr>
<tr>
<th>Send Account Info (WIP)</th>
<th>
<form action="http://{{clientip}}:{{port}}/account" method="post">
<div class="form-group">
<input type="text" class="form-control" name="account_text" placeholder='{ username: "", password: "" }'>
</div>
<button type='submit' class='btn btn-danger'>SEND</button>
</form>
</th>
</tr>
<tr>
<th>Send Pixel Check Location (WIP)</th>
<th>
<form action="http://{{clientip}}:{{port}}/pixel" method="post">
<div class="form-group">
<input type="text" class="form-control" name="pixel_text" placeholder="{}">
</div>
<button type='submit' class='btn btn-danger'>SEND</button>
</form>
</th>
</tr>
<tr>
<th>Send Touch Location (WIP)</th>
<th>
<form action="http://{{clientip}}:{{port}}/touch" method="post">
<div class="form-group">
<input type="text" class="form-control" name="touch_text" placeholder="{}">
</div>
<button type='submit' class='btn btn-danger'>SEND</button>
</form>
</th>
</tr>
<tr>
<th>Send Typing Data (WIP)</th>
<th>
<form action="http://{{clientip}}:{{port}}/type" method="post">
<div class="form-group">
<input type="text" class="form-control" name="type_text" placeholder="{}">
</div>
<button type='submit' class='btn btn-danger'>SEND</button>
</form>
</th>
</tr>
</tbody>
</table>
</div>
</body>
</html>

<script>
if ("{{style}}" === 'dark') {
$('body').css('background-color', 'rgb(33, 37, 41)');
$('body').css('color', 'rgb(255, 255, 255)');
//$('#header').css('color', 'white');
}
</script>
4 changes: 4 additions & 0 deletions src/views/device-new.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
{{/configs}}
</select>
</div>
<div class="form-group">
Device IP
<input type="text" class="form-control" name="clientip" value="" placeholder="192.168.1.2">
</div>
<br>
<button type="submit" class="btn btn-primary">Create</button>
<br>
Expand Down

0 comments on commit 9b42975

Please sign in to comment.