Browse Source

better admin stuff

master
mortie 7 years ago
parent
commit
efa3c805c0
4 changed files with 176 additions and 144 deletions
  1. 4
    3
      js/admin.js
  2. 14
    2
      js/fileserver.js
  3. 156
    139
      web/admin/lib.js
  4. 2
    0
      web/admin/view.js

+ 4
- 3
js/admin.js View File

@@ -154,12 +154,13 @@ function loginHandler(conf, req, respond) {
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;
sessTokens[id] = undefined;
}, 30 * 60 * 1000);

respond(null, token);
}
function validateToken(req) {
var token = req.headers["session-token"];
@@ -198,7 +199,7 @@ exports.serve = function(parts, conf, req, res) {

// Verify token
if (!validateToken(req))
return respond("Invalid token");
return respond("EINVALTOKEN");

var fn = methods[name];
if (!fn) {

+ 14
- 2
js/fileserver.js View File

@@ -5,6 +5,9 @@ var webroot = "web";

var files = {};
function file(wpath, fpath) {
if (typeof fpath === "object")
return files[wpath] = fpath;

if (fpath === undefined)
fpath = wpath;

@@ -22,10 +25,19 @@ file("/admin/view.js");

exports.canServe = canServe;
function canServe(parts) {
return files[parts.pathname] !== undefined;
return files[parts.pathname] || files[parts.pathname + "/"];
}

exports.serve = serve;
function serve(parts, res) {
res.end(files[parts.pathname]);
var f = files[parts.pathname];

if (!f && files[parts.pathname + "/"]) {
res.writeHead(302, {
location: parts.pathname+"/"
});
res.end();
} else {
res.end(f);
}
}

+ 156
- 139
web/admin/lib.js View File

@@ -1,163 +1,180 @@
var sessToken = "";
(function() {

window.apiLogin = apiLogin;
window.api = api;
window.elem = elem;
window.uploadEl = uploadEl;
window.async = async;
window.debounce = debounce;
window.error = error;
window.$$ = $$;

var sessToken = "";

function apiLogin(pass, cb) {
var extraHeads = [ [ "Session-Pass", pass ] ];

api("login", {}, (err, token) => {
if (token) {
sessToken = token;
cb(true);
} else {
cb(false);
}
}, extraHeads);
}

function argstr(args) {
return "?" + Object.keys(args).map(function(key) {
return encodeURIComponent(key)+"="+encodeURIComponent(args[key]);
}).join("&");
}

function apiLogin(pass, cb) {
var extraHeads = [ [ "Session-Pass", pass ] ];
function api(method, args, cb, extraHeads) {
var heads = new Headers();
heads.append("Session-Token", sessToken);
if (extraHeads)
extraHeads.forEach(h => heads.append(h[0], h[1]));

var opts = {
method: "POST",
headers: heads
};
fetch("/admin/api/"+method+argstr(args), opts)
.then(response => response.json())
.then(res => {
if (res.err && res.err === "EINVALTOKEN")
setView("login");
else
cb(res.err, res.obj)
});
}

api("login", {}, (err, token) => {
if (token) {
sessToken = token;
cb(true);
} else {
cb(false);
function elem(tag, props, children) {
var e;
if (tag instanceof HTMLElement)
e = tag;
else
e = document.createElement(tag);

if (props) {
for (var i in props) {
e[i] = props[i];
}
}
}, extraHeads);
}

function argstr(args) {
return "?" + Object.keys(args).map(function(key) {
return encodeURIComponent(key)+"="+encodeURIComponent(args[key]);
}).join("&");
}

function api(method, args, cb, extraHeads) {
var heads = new Headers();
heads.append("Session-Token", sessToken);
if (extraHeads)
extraHeads.forEach(h => heads.append(h[0], h[1]));

var opts = {
method: "POST",
headers: heads
};
fetch("/admin/api/"+method+argstr(args), opts)
.then(response => response.json())
.then(res => cb(res.err, res.obj));
}

function elem(tag, props, children) {
var e;
if (tag instanceof HTMLElement)
e = tag;
else
e = document.createElement(tag);

if (props) {
for (var i in props) {
e[i] = props[i];

if (children) {
for (var i in children) {
e.appendChild(children[i]);
}
}
}

if (children) {
for (var i in children) {
e.appendChild(children[i]);
e.appendTo = function(p) {
p.appendChild(e);
return e;
}
}

e.appendTo = function(p) {
p.appendChild(e);
return e;
}
e.on = function(name, fn) {
e.addEventListener(name, function(evt) {
fn.call(e, evt);
}, false);
return e;
}

e.on = function(name, fn) {
e.addEventListener(name, function(evt) {
fn.call(e, evt);
}, false);
return e;
}
e.addClass = function(name) {
if (e.className.indexOf(name) !== -1)
return e;

e.addClass = function(name) {
if (e.className.indexOf(name) !== -1)
e.className += " "+name;
return e;
}

e.className += " "+name;
return e;
}
e.removeClass = function(name) {
e.className = e.className
.replace(name, "")
.trim()
.replace(/ +/, "");
return e;
}

e.clear = function() {
var fc;
while (fc = e.firstChild)
e.removeChild(fc);
return e;
}

e.removeClass = function(name) {
e.className = e.className
.replace(name, "")
.trim()
.replace(/ +/, "");
return e;
}

e.clear = function() {
var fc;
while (fc = e.firstChild)
e.removeChild(fc);
return e;
var uploadElId = 0;
function uploadEl(args, cb) {
var id = uploadElId++;
var frame;
var form;
var fileEl;
return form = elem("form", {
className: "uploader",
action: "/admin/api/slide_file_upload"+argstr(args),
method: "post",
enctype: "multipart/form-data",
target: "upload-form-"+id
}, [
frame = elem("iframe", {
style: "display: none",
name: "upload-form-"+id
}).on("load", cb),

fileEl = elem("input", {
type: "file",
style: "display: none",
name: "file"
}).on("change", () => {
form.submit();
}),

elem("button", {
innerHTML: "Upload",
type: "button"
}).on("click", () => {
fileEl.click();
})
]);
}

return e;
}

var uploadElId = 0;
function uploadEl(args, cb) {
var id = uploadElId++;
var frame;
var form;
var fileEl;
return form = elem("form", {
className: "uploader",
action: "/admin/api/slide_file_upload"+argstr(args),
method: "post",
enctype: "multipart/form-data",
target: "upload-form-"+id
}, [
frame = elem("iframe", {
style: "display: none",
name: "upload-form-"+id
}).on("load", cb),

fileEl = elem("input", {
type: "file",
style: "display: none",
name: "file"
}).on("change", () => {
form.submit();
}),

elem("button", {
innerHTML: "Upload",
type: "button"
}).on("click", () => {
fileEl.click();
})
]);
}

function async(n, cb) {
var args = [];
return function(arg) {
args.push(arg);

n -= 1;
if (n === 0)
cb(args);
function async(n, cb) {
var args = [];
return function(arg) {
args.push(arg);

n -= 1;
if (n === 0)
cb(args);
}
}
}

function debounce(fn, ms) {
if (ms === undefined)
ms = 300;
function debounce(fn, ms) {
if (ms === undefined)
ms = 300;

var timeout;
return function() {
var timeout;
return function() {

if (timeout)
clearTimeout(timeout);
if (timeout)
clearTimeout(timeout);

timeout = setTimeout(function() {
fn();
timeout = null;
}, ms);
}
}
timeout = setTimeout(function() {
fn();
timeout = null;
}, ms);
}
}

function error(msg) {
alert(msg);
}
function error(msg) {
alert(msg);
}

var $$ = function() {
return elem(document.querySelector.apply(document, arguments));
}
function $$() {
return elem(document.querySelector.apply(document, arguments));
}
})();

+ 2
- 0
web/admin/view.js View File

@@ -1,5 +1,7 @@
(function() {

window.setView = setView;

var root = $$("#root");

var views = {

Loading…
Cancel
Save