jshinted all files
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"plugins": {
|
||||||
|
"es_modules": {}
|
||||||
|
},
|
||||||
|
"libs": [
|
||||||
|
"ecma5",
|
||||||
|
"ecma6"
|
||||||
|
],
|
||||||
|
"ecmaVersion": 6
|
||||||
|
}
|
||||||
+34
-34
@@ -50,8 +50,8 @@ frisby.create('Invalid posting 2')
|
|||||||
frisby.create('Invalid posting 3')
|
frisby.create('Invalid posting 3')
|
||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
action: 'POST',
|
action: 'POST',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: "assdss",
|
signature: 'assdss',
|
||||||
note: testNote
|
note: testNote
|
||||||
})
|
})
|
||||||
.expectStatus(400)
|
.expectStatus(400)
|
||||||
@@ -62,8 +62,8 @@ frisby.create('Invalid posting 3')
|
|||||||
frisby.create('Valid posting')
|
frisby.create('Valid posting')
|
||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
action: 'POST',
|
action: 'POST',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + testNote),
|
signature: md5(md5('new') + testNote),
|
||||||
password: '',
|
password: '',
|
||||||
note: testNote
|
note: testNote
|
||||||
})
|
})
|
||||||
@@ -81,39 +81,39 @@ frisby.create('Valid posting')
|
|||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
id: noteId,
|
id: noteId,
|
||||||
action: 'UPDATE',
|
action: 'UPDATE',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + testNote+'!!!'),
|
signature: md5(md5('new') + testNote+'!!!'),
|
||||||
note: testNote + '!!!',
|
note: testNote + '!!!',
|
||||||
password: ''
|
password: ''
|
||||||
})
|
})
|
||||||
.expectStatus(400)
|
.expectStatus(400)
|
||||||
.expectBodyContains('Password is wrong')
|
.expectBodyContains('Password is wrong')
|
||||||
.toss()
|
.toss();
|
||||||
})
|
})
|
||||||
.after((err, res, body) => {
|
.after((err, res, body) => {
|
||||||
frisby.create('Illegal note editing attempt')
|
frisby.create('Illegal note editing attempt')
|
||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
id: noteId,
|
id: noteId,
|
||||||
action: 'UPDATE',
|
action: 'UPDATE',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + testNote+'!!!'),
|
signature: md5(md5('new') + testNote+'!!!'),
|
||||||
note: testNote + '!!!',
|
note: testNote + '!!!',
|
||||||
password: "aaabbb"
|
password: 'aaabbb'
|
||||||
})
|
})
|
||||||
.expectStatus(400)
|
.expectStatus(400)
|
||||||
.expectBodyContains('Password is wrong')
|
.expectBodyContains('Password is wrong')
|
||||||
.toss()
|
.toss();
|
||||||
|
|
||||||
})
|
})
|
||||||
.toss()
|
.toss();
|
||||||
})
|
})
|
||||||
.toss();
|
.toss();
|
||||||
|
|
||||||
frisby.create('Valid posting, editing and removal')
|
frisby.create('Valid posting, editing and removal')
|
||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
action: 'POST',
|
action: 'POST',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + testNote),
|
signature: md5(md5('new') + testNote),
|
||||||
password: 'aabbcc',
|
password: 'aabbcc',
|
||||||
note: testNote
|
note: testNote
|
||||||
})
|
})
|
||||||
@@ -123,7 +123,7 @@ frisby.create('Valid posting, editing and removal')
|
|||||||
.after(function(err, res, body) {
|
.after(function(err, res, body) {
|
||||||
var noteId = body.replace('Found. Redirecting to /', '');
|
var noteId = body.replace('Found. Redirecting to /', '');
|
||||||
frisby.create('Export posted note')
|
frisby.create('Export posted note')
|
||||||
.get('http://localhost:3000/' + noteId + "/export")
|
.get('http://localhost:3000/' + noteId + '/export')
|
||||||
.expectStatus(200)
|
.expectStatus(200)
|
||||||
.expectHeaderContains('content-type', 'text/plain; charset=utf-8')
|
.expectHeaderContains('content-type', 'text/plain; charset=utf-8')
|
||||||
.expectBodyContains(testNote)
|
.expectBodyContains(testNote)
|
||||||
@@ -138,24 +138,24 @@ frisby.create('Valid posting, editing and removal')
|
|||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
id: noteId,
|
id: noteId,
|
||||||
action: 'UPDATE',
|
action: 'UPDATE',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + testNote+'!!!'),
|
signature: md5(md5('new') + testNote+'!!!'),
|
||||||
note: testNote + '!!!',
|
note: testNote + '!!!',
|
||||||
password: "abbcc"
|
password: 'abbcc'
|
||||||
})
|
})
|
||||||
.expectStatus(400)
|
.expectStatus(400)
|
||||||
.expectBodyContains('Password is wrong')
|
.expectBodyContains('Password is wrong')
|
||||||
.toss()
|
.toss();
|
||||||
})
|
})
|
||||||
.after((err, res, body) => {
|
.after((err, res, body) => {
|
||||||
frisby.create('Valid note editing attempt')
|
frisby.create('Valid note editing attempt')
|
||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
id: noteId,
|
id: noteId,
|
||||||
action: 'UPDATE',
|
action: 'UPDATE',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + 'Changed!'),
|
signature: md5(md5('new') + 'Changed!'),
|
||||||
note: 'Changed!',
|
note: 'Changed!',
|
||||||
password: "aabbcc"
|
password: 'aabbcc'
|
||||||
})
|
})
|
||||||
.expectStatus(302)
|
.expectStatus(302)
|
||||||
.after((err, res, body) => {
|
.after((err, res, body) => {
|
||||||
@@ -171,27 +171,27 @@ frisby.create('Valid posting, editing and removal')
|
|||||||
id: noteId,
|
id: noteId,
|
||||||
button: 'Delete',
|
button: 'Delete',
|
||||||
action: 'UPDATE',
|
action: 'UPDATE',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + 'Changed!'),
|
signature: md5(md5('new') + 'Changed!'),
|
||||||
note: 'Changed!',
|
note: 'Changed!',
|
||||||
password: "aabbcc"
|
password: 'aabbcc'
|
||||||
})
|
})
|
||||||
.expectStatus(200)
|
.expectStatus(200)
|
||||||
.expectBodyContains('Note deleted')
|
.expectBodyContains('Note deleted')
|
||||||
.toss();
|
.toss();
|
||||||
})
|
})
|
||||||
.toss()
|
.toss();
|
||||||
})
|
})
|
||||||
.toss()
|
.toss();
|
||||||
frisby.create('Read stats of posted note')
|
frisby.create('Read stats of posted note')
|
||||||
.expectStatus(200)
|
.expectStatus(200)
|
||||||
.get('http://localhost:3000/' + noteId).toss()
|
.get('http://localhost:3000/' + noteId).toss();
|
||||||
frisby.create('Read stats of posted note')
|
frisby.create('Read stats of posted note')
|
||||||
.expectStatus(200)
|
.expectStatus(200)
|
||||||
.get('http://localhost:3000/' + noteId).toss()
|
.get('http://localhost:3000/' + noteId).toss();
|
||||||
frisby.create('Read stats of posted note')
|
frisby.create('Read stats of posted note')
|
||||||
.expectStatus(200)
|
.expectStatus(200)
|
||||||
.get('http://localhost:3000/' + noteId).toss()
|
.get('http://localhost:3000/' + noteId).toss();
|
||||||
frisby.create('Read stats of posted note')
|
frisby.create('Read stats of posted note')
|
||||||
.get('http://localhost:3000/' + noteId + '/stats')
|
.get('http://localhost:3000/' + noteId + '/stats')
|
||||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||||
@@ -209,8 +209,8 @@ while (tooLongNote.length < 1024*200) tooLongNote += tooLongNote;
|
|||||||
frisby.create('Invalid posting of too long note')
|
frisby.create('Invalid posting of too long note')
|
||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
action: 'POST',
|
action: 'POST',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + testNote),
|
signature: md5(md5('new') + testNote),
|
||||||
password: 'aabbcc',
|
password: 'aabbcc',
|
||||||
note: tooLongNote
|
note: tooLongNote
|
||||||
})
|
})
|
||||||
@@ -222,8 +222,8 @@ frisby.create('Invalid posting of too long note')
|
|||||||
frisby.create('Invalid update without id')
|
frisby.create('Invalid update without id')
|
||||||
.post('http://localhost:3000/note', {
|
.post('http://localhost:3000/note', {
|
||||||
action: 'UPDATE',
|
action: 'UPDATE',
|
||||||
session: md5("new"),
|
session: md5('new'),
|
||||||
signature: md5(md5("new") + 'Any note'),
|
signature: md5(md5('new') + 'Any note'),
|
||||||
password: 'aabbcc',
|
password: 'aabbcc',
|
||||||
note: 'Any note'
|
note: 'Any note'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
var $ = function(id) {
|
var $ = function(id) {
|
||||||
return document.getElementById(id);
|
return document.getElementById(id);
|
||||||
}
|
};
|
||||||
var iosDetected = navigator.userAgent.match("(iPad|iPod|iPhone)");
|
var iosDetected = navigator.userAgent.match('(iPad|iPod|iPhone)');
|
||||||
var timer = null;
|
var timer = null;
|
||||||
var timerDelay = iosDetected ? 800 : 400;
|
var timerDelay = iosDetected ? 800 : 400;
|
||||||
var $note, $action, $preview, $plain_password, $tableau;
|
var $note, $action, $preview, $plain_password, $tableau;
|
||||||
@@ -21,10 +21,10 @@ function md2html(input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveDraft() {
|
function saveDraft() {
|
||||||
if ($action == "UPDATE") return;
|
if ($action == 'UPDATE') return;
|
||||||
console.log("draft autosave...");
|
console.log('draft autosave...');
|
||||||
$tableau.innerHTML = "Draft autosaved."
|
$tableau.innerHTML = 'Draft autosaved.';
|
||||||
localStorage.setItem("draft", $note.value);
|
localStorage.setItem('draft', $note.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableButton() {
|
function enableButton() {
|
||||||
@@ -34,40 +34,40 @@ function enableButton() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onLoad() {
|
function onLoad() {
|
||||||
$note = $("note");
|
$note = $('note');
|
||||||
$action = $("action").value;
|
$action = $('action').value;
|
||||||
$preview = $("draft");
|
$preview = $('draft');
|
||||||
$tableau = $("tableau");
|
$tableau = $('tableau');
|
||||||
$plain_password = $("plain-password");
|
$plain_password = $('plain-password');
|
||||||
var updatePreview = function() {
|
var updatePreview = function() {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
var content = $note.value;
|
var content = $note.value;
|
||||||
var delay = Math.min(timerDelay, timerDelay * (content.length / 400));
|
var delay = Math.min(timerDelay, timerDelay * (content.length / 400));
|
||||||
timer = setTimeout(function() {
|
timer = setTimeout(function() {
|
||||||
$preview.innerHTML = md2html(content);
|
$preview.innerHTML = md2html(content);
|
||||||
$tableau.innerHTML = content.split(/\s+/).length + " words";
|
$tableau.innerHTML = content.split(/\s+/).length + ' words';
|
||||||
}, delay);
|
}, delay);
|
||||||
};
|
};
|
||||||
if ($action == "UPDATE") updatePreview();
|
if ($action == 'UPDATE') updatePreview();
|
||||||
else {
|
else {
|
||||||
$("delete-button").style.display = "none";
|
$('delete-button').style.display = 'none';
|
||||||
$note.value = "";
|
$note.value = '';
|
||||||
var draft = localStorage.getItem("draft");
|
var draft = localStorage.getItem('draft');
|
||||||
if (draft) {
|
if (draft) {
|
||||||
$note.value = draft;
|
$note.value = draft;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$note.onkeyup = updatePreview;
|
$note.onkeyup = updatePreview;
|
||||||
$("delete-button").onclick = $("publish-button").onclick = function(e) {
|
$('delete-button').onclick = $('publish-button').onclick = function(e) {
|
||||||
localStorage.removeItem("draft");
|
localStorage.removeItem('draft');
|
||||||
self.onbeforeunload = null;
|
self.onbeforeunload = null;
|
||||||
if ($plain_password.value != "") $("password").value = md5($plain_password.value);
|
if ($plain_password.value !== '') $('password').value = md5($plain_password.value);
|
||||||
$plain_password.value = null;
|
$plain_password.value = null;
|
||||||
$("signature").value = md5($("session").value + $note.value.replace(/[\n\r]/g, ""));
|
$('signature').value = md5($('session').value + $note.value.replace(/[\n\r]/g, ''));
|
||||||
};
|
};
|
||||||
if (iosDetected) $note.className += " ui-border";
|
if (iosDetected) $note.className += ' ui-border';
|
||||||
else $note.focus();
|
else $note.focus();
|
||||||
self.onbeforeunload = saveDraft;
|
self.onbeforeunload = saveDraft;
|
||||||
setInterval(saveDraft, 60 * 1000)
|
setInterval(saveDraft, 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ var express = require('express');
|
|||||||
var view = require('./view');
|
var view = require('./view');
|
||||||
var storage = require('./storage');
|
var storage = require('./storage');
|
||||||
var md5 = require('md5');
|
var md5 = require('md5');
|
||||||
var LRU = require("lru-cache")
|
var LRU = require('lru-cache');
|
||||||
var bodyParser = require('body-parser');
|
var bodyParser = require('body-parser');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var blackList;
|
var blackList;
|
||||||
@@ -13,8 +13,8 @@ app.use(bodyParser.urlencoded({ extended: true, limit: '200kb' }));
|
|||||||
app.use(express.static(__dirname + '/resources/public'));
|
app.use(express.static(__dirname + '/resources/public'));
|
||||||
app.use(function (error, req, res, next) {
|
app.use(function (error, req, res, next) {
|
||||||
if (error) {
|
if (error) {
|
||||||
sendResponse(res, 400, "Bad request", error.message);
|
sendResponse(res, 400, 'Bad request', error.message);
|
||||||
log("REQUEST ERROR:", error);
|
log('REQUEST ERROR:', error);
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
@@ -24,28 +24,28 @@ var MODELS = {};
|
|||||||
var CACHE = new LRU({
|
var CACHE = new LRU({
|
||||||
max: 50,
|
max: 50,
|
||||||
dispose: key => {
|
dispose: key => {
|
||||||
log("disposing", key, "from cache");
|
log('disposing', key, 'from cache');
|
||||||
var model = MODELS[key];
|
var model = MODELS[key];
|
||||||
model && model.save();
|
if (model) model.save();
|
||||||
delete MODELS[key];
|
delete MODELS[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var log = function() {
|
var log = function() {
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
var timestamp = date.getDate() + "/" + date.getMonth() + " " + date.getHours() + ":" +
|
var timestamp = date.getDate() + '/' + date.getMonth() + ' ' + date.getHours() + ':' +
|
||||||
date.getMinutes() + ":" + date.getSeconds() + "." + date.getMilliseconds();
|
date.getMinutes() + ':' + date.getSeconds() + '.' + date.getMilliseconds();
|
||||||
var message = Array.prototype.slice.call(arguments);
|
var message = Array.prototype.slice.call(arguments);
|
||||||
message.unshift("--");
|
message.unshift('--');
|
||||||
message.unshift(timestamp);
|
message.unshift(timestamp);
|
||||||
console.log.apply(console, message);
|
console.log.apply(console, message);
|
||||||
}
|
};
|
||||||
|
|
||||||
app.get('/TOS', (req, res) => res.send(view.renderTOS()));
|
app.get('/TOS', (req, res) => res.send(view.renderTOS()));
|
||||||
|
|
||||||
app.get('/new', (req, res) => {
|
app.get('/new', (req, res) => {
|
||||||
log(req.ip, "opens /new");
|
log(req.ip, 'opens /new');
|
||||||
res.send(view.newNotePage(md5("new")));
|
res.send(view.newNotePage(md5('new')));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post('/note', (req, res) => {
|
app.post('/note', (req, res) => {
|
||||||
@@ -55,43 +55,43 @@ app.post('/note', (req, res) => {
|
|||||||
password = body.password,
|
password = body.password,
|
||||||
action = body.action,
|
action = body.action,
|
||||||
id = body.id;
|
id = body.id;
|
||||||
log(req.ip, "calls /note to", action, id);
|
log(req.ip, 'calls /note to', action, id);
|
||||||
var goToNote = note => res.redirect("/" + note.id);
|
var goToNote = note => res.redirect('/' + note.id);
|
||||||
if (!note || !session || session.indexOf(md5('edit/' + id)) != 0 && session.indexOf(md5('new')) != 0)
|
if (!note || !session || session.indexOf(md5('edit/' + id)) !== 0 && session.indexOf(md5('new')) !== 0)
|
||||||
return sendResponse(res, 400, 'Bad request');
|
return sendResponse(res, 400, 'Bad request');
|
||||||
if (body.signature != md5(session + note.replace(/[\n\r]/g, "")))
|
if (body.signature != md5(session + note.replace(/[\n\r]/g, '')))
|
||||||
return sendResponse(res, 400, "Signature mismatch");
|
return sendResponse(res, 400, 'Signature mismatch');
|
||||||
if (action == "POST")
|
if (action == 'POST')
|
||||||
storage.addNote(note, password).then(goToNote);
|
storage.addNote(note, password).then(goToNote);
|
||||||
else {
|
else {
|
||||||
if (!id) return sendResponse(res, 400, "Wrong note ID");
|
if (!id) return sendResponse(res, 400, 'Wrong note ID');
|
||||||
CACHE.del(id);
|
CACHE.del(id);
|
||||||
if (body.button == "Delete") {
|
if (body.button == 'Delete') {
|
||||||
log("deleting note", id);
|
log('deleting note', id);
|
||||||
storage.deleteNote(id, password).then(
|
storage.deleteNote(id, password).then(
|
||||||
() => sendResponse(res, 200, "Note deleted"),
|
() => sendResponse(res, 200, 'Note deleted'),
|
||||||
error => sendResponse(res, 400, "Bad request", error.message));
|
error => sendResponse(res, 400, 'Bad request', error.message));
|
||||||
} else {
|
} else {
|
||||||
log("updating note", id);
|
log('updating note', id);
|
||||||
storage.updateNote(id, password, note).then(goToNote,
|
storage.updateNote(id, password, note).then(goToNote,
|
||||||
error => sendResponse(res, 400, "Bad request", error.message));
|
error => sendResponse(res, 400, 'Bad request', error.message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/:year/:month/:day/:title", (req, res) => {
|
app.get('/:year/:month/:day/:title', (req, res) => {
|
||||||
var P = req.params, url = P.year + "/" + P.month + "/" + P.day + "/" + P.title;
|
var P = req.params, url = P.year + '/' + P.month + '/' + P.day + '/' + P.title;
|
||||||
log(req.ip, "resolves deprecated id", url);
|
log(req.ip, 'resolves deprecated id', url);
|
||||||
if (CACHE.has(url)) {
|
if (CACHE.has(url)) {
|
||||||
log(url, "is cached!");
|
log(url, 'is cached!');
|
||||||
var id = CACHE.get(url);
|
var id = CACHE.get(url);
|
||||||
if (id) res.redirect("/" + id);
|
if (id) res.redirect('/' + id);
|
||||||
else notFound(res);
|
else notFound(res);
|
||||||
} else storage.getNoteId(url).then(note => {
|
} else storage.getNoteId(url).then(note => {
|
||||||
log(url, "is not cached, resolving...");
|
log(url, 'is not cached, resolving...');
|
||||||
if (note) {
|
if (note) {
|
||||||
CACHE.set(url, note.id);
|
CACHE.set(url, note.id);
|
||||||
res.redirect("/" + note.id)
|
res.redirect('/' + note.id);
|
||||||
} else {
|
} else {
|
||||||
CACHE.set(url, null);
|
CACHE.set(url, null);
|
||||||
notFound(res);
|
notFound(res);
|
||||||
@@ -100,44 +100,44 @@ app.get("/:year/:month/:day/:title", (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.get(/\/([a-z0-9]+)\/edit/, (req, res) => {
|
app.get(/\/([a-z0-9]+)\/edit/, (req, res) => {
|
||||||
var id = req.params["0"];
|
var id = req.params['0'];
|
||||||
log(req.ip, "calls /edit on", id);
|
log(req.ip, 'calls /edit on', id);
|
||||||
storage.getNote(id).then(note => res.send(note
|
storage.getNote(id).then(note => res.send(note ?
|
||||||
? view.editNotePage(md5('edit/' + id), note)
|
view.editNotePage(md5('edit/' + id), note) :
|
||||||
: notFound(res)));
|
notFound(res)));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get(/\/([a-z0-9]+)\/export/, (req, res) => {
|
app.get(/\/([a-z0-9]+)\/export/, (req, res) => {
|
||||||
var id = req.params["0"];
|
var id = req.params['0'];
|
||||||
log(req.ip, "calls /export on", id);
|
log(req.ip, 'calls /export on', id);
|
||||||
res.set({ 'Content-Type': 'text/plain', 'Charset': 'utf-8' });
|
res.set({ 'Content-Type': 'text/plain', 'Charset': 'utf-8' });
|
||||||
storage.getNote(id).then(note => note
|
storage.getNote(id).then(note => note ?
|
||||||
? res.send(note.text)
|
res.send(note.text) :
|
||||||
: notFound(res));
|
notFound(res));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get(/\/([a-z0-9]+)\/stats/, (req, res) => {
|
app.get(/\/([a-z0-9]+)\/stats/, (req, res) => {
|
||||||
var id = req.params["0"];
|
var id = req.params['0'];
|
||||||
log(req.ip, "calls /stats on", id);
|
log(req.ip, 'calls /stats on', id);
|
||||||
var promise = id in MODELS
|
var promise = id in MODELS ?
|
||||||
? new Promise(resolve => resolve(MODELS[id]))
|
new Promise(resolve => resolve(MODELS[id])) :
|
||||||
: storage.getNote(id);
|
storage.getNote(id);
|
||||||
promise.then(note => note
|
promise.then(note => note ?
|
||||||
? res.send(view.renderStats(note))
|
res.send(view.renderStats(note)) :
|
||||||
: notFound(res));
|
notFound(res));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get(/\/([a-z0-9]+)/, (req, res) => {
|
app.get(/\/([a-z0-9]+)/, (req, res) => {
|
||||||
var id = req.params["0"];
|
var id = req.params['0'];
|
||||||
log(req.ip, "open note", id, "from", req.get("Referer"));
|
log(req.ip, 'open note', id, 'from', req.get('Referer'));
|
||||||
if (CACHE.has(id)) {
|
if (CACHE.has(id)) {
|
||||||
log(id, "is cached!");
|
log(id, 'is cached!');
|
||||||
var note = MODELS[id];
|
var obj = MODELS[id];
|
||||||
if (!note) return notFound(res);
|
if (!obj) return notFound(res);
|
||||||
note.views++;
|
obj.views++;
|
||||||
res.send(CACHE.get(id));
|
res.send(CACHE.get(id));
|
||||||
} else storage.getNote(id).then(note => {
|
} else storage.getNote(id).then(note => {
|
||||||
log(id, "is not cached, resolving...");
|
log(id, 'is not cached, resolving...');
|
||||||
if (!note) {
|
if (!note) {
|
||||||
CACHE.set(id, null);
|
CACHE.set(id, null);
|
||||||
return notFound(res);
|
return notFound(res);
|
||||||
@@ -151,31 +151,31 @@ app.get(/\/([a-z0-9]+)/, (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var sendResponse = (res, code, message, details) => {
|
var sendResponse = (res, code, message, details) => {
|
||||||
log("sending response", code, message);
|
log('sending response', code, message);
|
||||||
res.status(code).send(view.renderPage(null, message,
|
res.status(code).send(view.renderPage(null, message,
|
||||||
`<h1>${message}</h1><br/>` +
|
`<h1>${message}</h1><br/>` +
|
||||||
`<center>${details || "¯\\_(ツ)_/¯"}</center>`, ""));
|
`<center>${details || '¯\\_(ツ)_/¯'}</center>`, ''));
|
||||||
}
|
};
|
||||||
|
|
||||||
var notFound = res => sendResponse(res, 404, "Not found");
|
var notFound = res => sendResponse(res, 404, 'Not found');
|
||||||
|
|
||||||
var server = app.listen(process.env.PORT || 3000,
|
var server = app.listen(process.env.PORT || 3000,
|
||||||
() => log('NoteHub server listening on port', server.address().port));
|
() => log('NoteHub server listening on port', server.address().port));
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
var keys = Object.keys(MODELS);
|
var keys = Object.keys(MODELS);
|
||||||
log("saving stats for", keys.length, "models...");
|
log('saving stats for', keys.length, 'models...');
|
||||||
keys.forEach(id => MODELS[id].save())
|
keys.forEach(id => MODELS[id].save());
|
||||||
}, 5 * 60 * 1000);
|
}, 5 * 60 * 1000);
|
||||||
|
|
||||||
var updateBlackList = () => {
|
var updateBlackList = () => {
|
||||||
var ids = fs.readFileSync(process.env.BLACK_LIST || "/dev/null", "utf-8").split(/\n+/).filter(Boolean);
|
var ids = fs.readFileSync(process.env.BLACK_LIST || '/dev/null', 'utf-8').split(/\n+/).filter(Boolean);
|
||||||
ids.forEach(id => CACHE.del(id))
|
ids.forEach(id => CACHE.del(id));
|
||||||
blackList = new Set(ids);
|
blackList = new Set(ids);
|
||||||
log("black list updated, entries:", blackList.size);
|
log('black list updated, entries:', blackList.size);
|
||||||
};
|
};
|
||||||
|
|
||||||
setInterval(updateBlackList, 60 * 60 * 1000)
|
setInterval(updateBlackList, 60 * 60 * 1000);
|
||||||
|
|
||||||
updateBlackList();
|
updateBlackList();
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -32,7 +32,7 @@ var generateId = () => [1, 1, 1, 1, 1]
|
|||||||
var code = Math.floor(Math.random() * 36);
|
var code = Math.floor(Math.random() * 36);
|
||||||
return String.fromCharCode(code + (code < 10 ? 48 : 87));
|
return String.fromCharCode(code + (code < 10 ? 48 : 87));
|
||||||
})
|
})
|
||||||
.join("");
|
.join('');
|
||||||
|
|
||||||
var getFreeId = () => {
|
var getFreeId = () => {
|
||||||
var id = generateId();
|
var id = generateId();
|
||||||
@@ -46,9 +46,9 @@ module.exports.addNote = (note, password) => getFreeId().then(id => Note.create(
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
var passwordCheck = (note, password, callback) =>
|
var passwordCheck = (note, password, callback) =>
|
||||||
(!note || note.password.length == 0 || note.password !== password)
|
(!note || note.password.length === 0 || note.password !== password) ?
|
||||||
? new Promise((resolve, reject) => reject({ message: "Password is wrong" }))
|
new Promise((resolve, reject) => reject({ message: 'Password is wrong' })) :
|
||||||
: callback();
|
callback();
|
||||||
|
|
||||||
module.exports.updateNote = (id, password, text) =>
|
module.exports.updateNote = (id, password, text) =>
|
||||||
Note.findById(id).then(note =>
|
Note.findById(id).then(note =>
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
var marked = require("marked");
|
var marked = require('marked');
|
||||||
var fs = require("fs");
|
var fs = require('fs');
|
||||||
var hljs = require("highlight.js");
|
var hljs = require('highlight.js');
|
||||||
|
|
||||||
var TOS = fs.readFileSync("resources/TOS.md", "utf-8");
|
var TOS = fs.readFileSync('resources/TOS.md', 'utf-8');
|
||||||
var pageTemplate = fs.readFileSync("resources/template.html", "utf-8");
|
var pageTemplate = fs.readFileSync('resources/template.html', 'utf-8');
|
||||||
var footerTemplate = fs.readFileSync("resources/footer.html", "utf-8");
|
var footerTemplate = fs.readFileSync('resources/footer.html', 'utf-8');
|
||||||
var editTemplate = fs.readFileSync("resources/edit.html", "utf-8");
|
var editTemplate = fs.readFileSync('resources/edit.html', 'utf-8');
|
||||||
var header = fs.readFileSync(process.env.HEADER || "/dev/null", "utf-8");
|
var header = fs.readFileSync(process.env.HEADER || '/dev/null', 'utf-8');
|
||||||
|
|
||||||
var deriveTitle = text => text
|
var deriveTitle = text => text
|
||||||
.split(/[\n\r]/)[0].slice(0,25)
|
.split(/[\n\r]/)[0].slice(0,25)
|
||||||
.replace(/[`~!@#\$%^&\*_|\+=\?;:'",.<>\{\}\\\/]/g, "");
|
.replace(/[`~!@#\$%^&\*_|\+=\?;:'",.<>\{\}\\\/]/g, '');
|
||||||
|
|
||||||
var renderPage = (id, title, content, footer, blackList) => pageTemplate
|
var renderPage = (id, title, content, footer, blackList) => pageTemplate
|
||||||
.replace("%HEADER%", blackList && blackList.has(id) ? header : "")
|
.replace('%HEADER%', blackList && blackList.has(id) ? header : '')
|
||||||
.replace("%TITLE%", title)
|
.replace('%TITLE%', title)
|
||||||
.replace("%CONTENT%", content.replace(/<meta.*?>/gi, "").replace(/<script[\s\S.]*?\/script>/gi, ""))
|
.replace('%CONTENT%', content.replace(/<meta.*?>/gi, '').replace(/<script[\s\S.]*?\/script>/gi, ''))
|
||||||
.replace("%FOOTER%", footer || "");
|
.replace('%FOOTER%', footer || '');
|
||||||
|
|
||||||
marked.setOptions({
|
marked.setOptions({
|
||||||
langPrefix: "hljs lang-",
|
langPrefix: 'hljs lang-',
|
||||||
highlight: code => hljs.highlightAuto(code).value,
|
highlight: code => hljs.highlightAuto(code).value,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -29,11 +29,11 @@ module.exports.renderStats = note => renderPage(note.id, deriveTitle(note.text),
|
|||||||
`<h2>Statistics</h2>
|
`<h2>Statistics</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr><td>Published</td><td>${note.published}</td></tr>
|
<tr><td>Published</td><td>${note.published}</td></tr>
|
||||||
<tr><td>Edited</td><td>${note.edited || "N/A"}</td></tr>
|
<tr><td>Edited</td><td>${note.edited || 'N/A'}</td></tr>
|
||||||
<tr><td>Views</td><td>${note.views}</td></tr>
|
<tr><td>Views</td><td>${note.views}</td></tr>
|
||||||
</table>`);
|
</table>`);
|
||||||
|
|
||||||
module.exports.renderTOS = () => renderPage("tos", "Terms of Service", marked(TOS));
|
module.exports.renderTOS = () => renderPage('tos', 'Terms of Service', marked(TOS));
|
||||||
|
|
||||||
module.exports.renderNote = (note, blackList) => renderPage(note.id,
|
module.exports.renderNote = (note, blackList) => renderPage(note.id,
|
||||||
deriveTitle(note.text),
|
deriveTitle(note.text),
|
||||||
@@ -42,14 +42,14 @@ module.exports.renderNote = (note, blackList) => renderPage(note.id,
|
|||||||
blackList);
|
blackList);
|
||||||
|
|
||||||
module.exports.newNotePage = session => editTemplate
|
module.exports.newNotePage = session => editTemplate
|
||||||
.replace("%ACTION%", "POST")
|
.replace('%ACTION%', 'POST')
|
||||||
.replace("%SESSION%", session)
|
.replace('%SESSION%', session)
|
||||||
.replace("%CONTENT%", "Loading...");
|
.replace('%CONTENT%', 'Loading...');
|
||||||
|
|
||||||
module.exports.editNotePage = (session, note) => editTemplate
|
module.exports.editNotePage = (session, note) => editTemplate
|
||||||
.replace("%ACTION%", "UPDATE")
|
.replace('%ACTION%', 'UPDATE')
|
||||||
.replace("%SESSION%", session)
|
.replace('%SESSION%', session)
|
||||||
.replace("%ID%", note.id)
|
.replace('%ID%', note.id)
|
||||||
.replace("%CONTENT%", escape$(note.text));
|
.replace('%CONTENT%', escape$(note.text));
|
||||||
|
|
||||||
var escape$ = s => s.split("").map(chr => chr == "$" ? "$$" : chr).join("");
|
var escape$ = s => s.split('').map(chr => chr == '$' ? '$$' : chr).join('');
|
||||||
|
|||||||
Reference in New Issue
Block a user