|
|
@@ -2,9 +2,12 @@ var querystring = require("querystring"); |
|
|
|
var fs = require("fs"); |
|
|
|
var pathlib = require("path"); |
|
|
|
var formidable = require("formidable"); |
|
|
|
var crypto = require("crypto"); |
|
|
|
|
|
|
|
var basepath = "/admin/api/"; |
|
|
|
|
|
|
|
var tokens = {}; |
|
|
|
|
|
|
|
// Used in every method handler to make sure the correct arguments are provided |
|
|
|
function hasargs(query, respond, expected) { |
|
|
|
var missing = []; |
|
|
@@ -134,23 +137,46 @@ var methods = { |
|
|
|
|
|
|
|
exports.canServe = function(parts) { |
|
|
|
// Temporary, while working on stuff |
|
|
|
return false; |
|
|
|
return methods[parts.pathname.replace(basepath, "")] !== undefined; |
|
|
|
var name = parts.pathname.replace(basepath, ""); |
|
|
|
return methods[name] !== undefined || name === "login"; |
|
|
|
} |
|
|
|
|
|
|
|
exports.serve = function(parts, conf, req, res) { |
|
|
|
var fn = methods[parts.pathname.replace(basepath, "")]; |
|
|
|
if (!fn) { |
|
|
|
res.writeHead(404); |
|
|
|
res.end(); |
|
|
|
return; |
|
|
|
} |
|
|
|
var sessTokens = []; |
|
|
|
function loginHandler(conf, req, respond) { |
|
|
|
var pass = req.headers["session-pass"]; |
|
|
|
if (!conf.password) |
|
|
|
return respond(null, false); |
|
|
|
if (!pass) |
|
|
|
return respond(null, false); |
|
|
|
if (pass !== conf.password) |
|
|
|
return respond(null, false); |
|
|
|
|
|
|
|
var token = crypto.randomBytes(16).toString("hex"); |
|
|
|
var id = sessTokens.length; |
|
|
|
sessTokens[id] = token; |
|
|
|
respond(null, token); |
|
|
|
|
|
|
|
// Time out after 30 minutes |
|
|
|
setTimeout(() => { |
|
|
|
tokens[id] = undefined; |
|
|
|
}, 30 * 60 * 1000); |
|
|
|
} |
|
|
|
function validateToken(req) { |
|
|
|
var token = req.headers["session-token"]; |
|
|
|
if (!token) |
|
|
|
return false; |
|
|
|
|
|
|
|
var query = querystring.parse(parts.query); |
|
|
|
for (var i in query) { |
|
|
|
query[i] = decodeURIComponent(query[i]); |
|
|
|
for (var i = 0; i < sessTokens.length; ++i) { |
|
|
|
if (sessTokens[i] && sessTokens[i] === token) |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
exports.serve = function(parts, conf, req, res) { |
|
|
|
var name = parts.pathname.replace(basepath, ""); |
|
|
|
|
|
|
|
// Better than manually doing res.end(JSON.stringify(obj)) everywhere |
|
|
|
function respond(err, obj) { |
|
|
|
var result = { |
|
|
@@ -166,6 +192,26 @@ exports.serve = function(parts, conf, req, res) { |
|
|
|
res.end(JSON.stringify(result)); |
|
|
|
} |
|
|
|
|
|
|
|
// Special login handler |
|
|
|
if (name === "login") |
|
|
|
return loginHandler(conf, req, respond); |
|
|
|
|
|
|
|
// Verify token |
|
|
|
if (!validateToken(req)) |
|
|
|
return respond("Invalid token"); |
|
|
|
|
|
|
|
var fn = methods[name]; |
|
|
|
if (!fn) { |
|
|
|
res.writeHead(404); |
|
|
|
res.end(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var query = querystring.parse(parts.query); |
|
|
|
for (var i in query) { |
|
|
|
query[i] = decodeURIComponent(query[i]); |
|
|
|
} |
|
|
|
|
|
|
|
// Finally, call method handler |
|
|
|
fn(query, conf, req, respond); |
|
|
|
} |