const express = require('express'); const bodyParser = require('body-parser'); const axios = require('axios'); const app = express(); const AUTH_SERVER_URL = 'http://localhost:8000'; // Enums const lockStates = { LOCK_OFF: 0, LOCK_PREARM: 1, LOCK_ARMED: 2, LOCK_ON_PRESSED: 3, LOCK_ON: 4, }; let toolStatus = null; const server = app.listen(8080, () => { console.log('Example app listening on port 8080!'); }); const io = require('socket.io')(server); // Express http server stuff: // TODO : remove on prod app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); next(); }); app.use(bodyParser.json()); app.post('/api/lockout/:mac', (req, res) => { if (toolStatus) { const mac = req.params.mac; console.log('Request from MAC:', mac, ': ', JSON.stringify(req.body)); const tmp = Object.entries(toolStatus).find(x => x[1].mac == mac) const toolSlug = tmp ? tmp[0] : null; if (toolSlug) { let clearAction = false; let tool = toolStatus[toolSlug]; tool.lastState = tool.state; switch (req.body.lockState) { case lockStates.LOCK_OFF: tool.state = 'off'; if (tool.action == 'disarm') clearAction = true; break; case lockStates.LOCK_ARMED: tool.state = 'armed'; if (tool.action == 'arm') clearAction = true; break; case lockStates.LOCK_ON: tool.state = 'on'; break; default: break; } // Track in case state is switched from elsewhere if (tool.state != tool.lastState) clearAction = true; if (clearAction) { tool.action = ''; console.log(tool); io.sockets.emit('toolStatus', toolStatus); } res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify({ action: tool.action })); toolStatus[toolSlug] = tool; } else { res.sendStatus(404); } } else { res.sendStatus(503); } }); app.get('*', (req, res) => { res.sendStatus(404); }); // Socket.io websocket stuff: // TODO : remove on prod io.origins('*:*'); io.on('connection', socket => { socket.emit('toolStatus', toolStatus); socket.on('requestInterlock', data => { console.log('Interlock change requested: ', JSON.stringify(data)); const token = data.token; const toolSlug = data.change.toolSlug; const action = data.change.action; axios.get(AUTH_SERVER_URL + '/user/', { headers: {'Authorization': 'Token ' + token}, }) .then(res => { const profile = res.data[0].profile || null; if (profile && profile.authorized_tools.includes(toolSlug)) { toolStatus[toolSlug].action = action; console.log(profile.user, action, toolSlug); io.sockets.emit('toolStatus', toolStatus); } }) .catch(err => console.log(err.message) ); }); }); setInterval(() => { axios.get(AUTH_SERVER_URL + '/tooldata/') .then(res => { toolStatus = res.data.categories .reduce((a, x) => a.concat(x.tools), []) .reduce((a, x) => ({...a, [x.slug]: a[x.slug] ? { ...a[x.slug], mac: x.mac } : { mac: x.mac, action: '', state: 'off', lastState: 'n/a' }}), toolStatus || {}); io.sockets.emit('toolStatus', toolStatus); }) .catch(err => console.log(err.message) ); }, 10000);