Fix up paths; add basic About page; strip tags from input
This commit is contained in:
parent
d7e77dc4dc
commit
e2a265783e
|
@ -21,6 +21,7 @@
|
||||||
"snarkdown": "^1.2.2",
|
"snarkdown": "^1.2.2",
|
||||||
"socket.io": "^2.2.0",
|
"socket.io": "^2.2.0",
|
||||||
"socket.io-client": "^2.2.0",
|
"socket.io-client": "^2.2.0",
|
||||||
|
"striptags": "^3.1.1",
|
||||||
"unused-filename": "^1.0.0"
|
"unused-filename": "^1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
server.js
59
server.js
|
@ -8,6 +8,7 @@ const bodyParser = require('body-parser');
|
||||||
const fileUpload = require('express-fileupload');
|
const fileUpload = require('express-fileupload');
|
||||||
const filenamify = require('filenamify');
|
const filenamify = require('filenamify');
|
||||||
const unusedFilename = require('unused-filename');
|
const unusedFilename = require('unused-filename');
|
||||||
|
const striptags = require('striptags');
|
||||||
const snarkdown = require('snarkdown');
|
const snarkdown = require('snarkdown');
|
||||||
const fecha = require('fecha');
|
const fecha = require('fecha');
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ function Server () {
|
||||||
this.server.use('/js', express.static(path.resolve('./node_modules/socket.io-client/dist/')));
|
this.server.use('/js', express.static(path.resolve('./node_modules/socket.io-client/dist/')));
|
||||||
|
|
||||||
this.server.get('/', (req, res) => {
|
this.server.get('/', (req, res) => {
|
||||||
const html = this.generateHomePage();
|
const html = this.generateHomePage(req);
|
||||||
if (html) {
|
if (html) {
|
||||||
res.send(html);
|
res.send(html);
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,11 +55,13 @@ function Server () {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.server.get('/give', (req, res) => {
|
this.server.get('/give', (req, res) => {
|
||||||
const body = this.fillTemplate('./templates/pages/uploadForm.html');
|
const resourcePath = (req.url.substr(-1) === '/' ? '../' : './');
|
||||||
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', body });
|
const body = this.fillTemplate('./templates/pages/uploadForm.html', { resourcePath });
|
||||||
|
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', resourcePath, body });
|
||||||
res.send(html);
|
res.send(html);
|
||||||
});
|
});
|
||||||
this.server.post('/give', (req, res) => {
|
this.server.post('/give', (req, res) => {
|
||||||
|
const resourcePath = (req.url.substr(-1) === '/' ? '../' : './');
|
||||||
if (Object.keys(req.files).length > 0
|
if (Object.keys(req.files).length > 0
|
||||||
&& req.body.hasOwnProperty('title') && req.body.title.trim() !== ''
|
&& req.body.hasOwnProperty('title') && req.body.title.trim() !== ''
|
||||||
&& req.body.hasOwnProperty('summary') && req.body.summary.trim() !== '') {
|
&& req.body.hasOwnProperty('summary') && req.body.summary.trim() !== '') {
|
||||||
|
@ -76,7 +79,7 @@ function Server () {
|
||||||
content: messageBox,
|
content: messageBox,
|
||||||
});
|
});
|
||||||
const body = this.fillTemplate('./templates/pages/uploadForm.html');
|
const body = this.fillTemplate('./templates/pages/uploadForm.html');
|
||||||
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', body, modal });
|
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', resourcePath, body, modal });
|
||||||
res.send(html);
|
res.send(html);
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
const messageBox = this.fillTemplate('./templates/elements/messageBox.html', {
|
const messageBox = this.fillTemplate('./templates/elements/messageBox.html', {
|
||||||
|
@ -89,7 +92,7 @@ function Server () {
|
||||||
content: messageBox,
|
content: messageBox,
|
||||||
});
|
});
|
||||||
const body = this.fillTemplate('./templates/pages/uploadForm.html');
|
const body = this.fillTemplate('./templates/pages/uploadForm.html');
|
||||||
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', body, modal });
|
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', resourcePath, body, modal });
|
||||||
res.send(html);
|
res.send(html);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -109,13 +112,23 @@ function Server () {
|
||||||
message: errorMessage,
|
message: errorMessage,
|
||||||
});
|
});
|
||||||
const body = this.fillTemplate('./templates/pages/uploadForm.html');
|
const body = this.fillTemplate('./templates/pages/uploadForm.html');
|
||||||
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', body, message });
|
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', resourcePath, body, message });
|
||||||
res.send(html);
|
res.send(html);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.server.get('/history', (req, res) => {
|
this.server.get('/history', (req, res) => {
|
||||||
const html = this.generateHistoryPage();
|
const html = this.generateHistoryPage(req);
|
||||||
|
if (html) {
|
||||||
|
res.send(html);
|
||||||
|
} else {
|
||||||
|
res.send('Something went wrong!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.server.get('/about', (req, res) => {
|
||||||
|
const body = this.fillTemplate('./templates/pages/about.html');
|
||||||
|
const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'About', body });
|
||||||
if (html) {
|
if (html) {
|
||||||
res.send(html);
|
res.send(html);
|
||||||
} else {
|
} else {
|
||||||
|
@ -173,7 +186,7 @@ Server.prototype.fillTemplate = function (file, templateVars = {}) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Server.prototype.generateHomePage = function () {
|
Server.prototype.generateHomePage = function (req) {
|
||||||
const files = fs.readdirSync(this.fileLocation).filter(fileName => fileName.includes('.json'));
|
const files = fs.readdirSync(this.fileLocation).filter(fileName => fileName.includes('.json'));
|
||||||
const books = files.map(fileName => {
|
const books = files.map(fileName => {
|
||||||
const bookData = JSON.parse(fs.readFileSync(path.resolve(this.fileLocation, fileName), 'utf8'));
|
const bookData = JSON.parse(fs.readFileSync(path.resolve(this.fileLocation, fileName), 'utf8'));
|
||||||
|
@ -181,13 +194,13 @@ Server.prototype.generateHomePage = function () {
|
||||||
|
|
||||||
const id = fileName.replace('.json', '');
|
const id = fileName.replace('.json', '');
|
||||||
const confirmId = 'confirm_' + id;
|
const confirmId = 'confirm_' + id;
|
||||||
const added = fecha.format(new Date(bookData.added), 'dddd MMMM Do, YYYY');
|
const added = fecha.format(new Date(bookData.added), 'hh:mm:ssA on dddd MMMM Do, YYYY');
|
||||||
const modal = this.fillTemplate('./templates/elements/modalCard.html', {
|
const modal = this.fillTemplate('./templates/elements/modalCard.html', {
|
||||||
id,
|
id,
|
||||||
header: '<h2 class="title">' + bookData.title + '</h2><h4 class="subtitle">' + bookData.author + '</h4>',
|
header: '<h2 class="title">' + bookData.title + '</h2><h4 class="subtitle">' + bookData.author + '</h4>',
|
||||||
content: this.fillTemplate('./templates/elements/bookInfo.html', {
|
content: this.fillTemplate('./templates/elements/bookInfo.html', {
|
||||||
contributor: bookData.contributor,
|
contributor: bookData.contributor,
|
||||||
fileFormat: bookData.fileFormat,
|
fileFormat: bookData.fileType,
|
||||||
added,
|
added,
|
||||||
summary: snarkdown(bookData.summary),
|
summary: snarkdown(bookData.summary),
|
||||||
})
|
})
|
||||||
|
@ -209,16 +222,20 @@ Server.prototype.generateHomePage = function () {
|
||||||
});
|
});
|
||||||
}).join('');
|
}).join('');
|
||||||
const body = '<div class="columns is-multiline">' + books + '</div>';
|
const body = '<div class="columns is-multiline">' + books + '</div>';
|
||||||
return this.fillTemplate('./templates/htmlContainer.html', { title: 'View', body });
|
return this.fillTemplate('./templates/htmlContainer.html', {
|
||||||
|
title: 'View',
|
||||||
|
resourcePath: (req.url.substr(-1) === '/' ? '../' : './'),
|
||||||
|
body
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Server.prototype.generateHistoryPage = function () {
|
Server.prototype.generateHistoryPage = function (req) {
|
||||||
const files = fs.readdirSync(this.historyLocation).filter(fileName => fileName.includes('.json'));
|
const files = fs.readdirSync(this.historyLocation).filter(fileName => fileName.includes('.json'));
|
||||||
const history = files.map(fileName => {
|
const history = files.map(fileName => {
|
||||||
const bookData = JSON.parse(fs.readFileSync(path.resolve(this.historyLocation, fileName), 'utf8'));
|
const bookData = JSON.parse(fs.readFileSync(path.resolve(this.historyLocation, fileName), 'utf8'));
|
||||||
const id = fileName.replace('.json', '');
|
const id = fileName.replace('.json', '');
|
||||||
const added = fecha.format(new Date(bookData.added), 'dddd MMMM Do, YYYY');
|
const added = fecha.format(new Date(bookData.added), 'hh:mm:ssA on dddd MMMM Do, YYYY');
|
||||||
const removed = fecha.format(new Date(parseInt(id)), 'dddd MMMM Do, YYYY');
|
const removed = fecha.format(new Date(parseInt(id)), 'hh:mm:ssA on dddd MMMM Do, YYYY');
|
||||||
const removedTag = '<div class="control"><div class="tags has-addons"><span class="tag">Taken</span><span class="tag is-primary">' + removed + '</span></div></div>';
|
const removedTag = '<div class="control"><div class="tags has-addons"><span class="tag">Taken</span><span class="tag is-primary">' + removed + '</span></div></div>';
|
||||||
const modal = this.fillTemplate('./templates/elements/modalCard.html', {
|
const modal = this.fillTemplate('./templates/elements/modalCard.html', {
|
||||||
id,
|
id,
|
||||||
|
@ -241,7 +258,11 @@ Server.prototype.generateHistoryPage = function () {
|
||||||
});
|
});
|
||||||
}).join('');
|
}).join('');
|
||||||
const body = '<div class="columns is-multiline">' + history + '</div>';
|
const body = '<div class="columns is-multiline">' + history + '</div>';
|
||||||
return this.fillTemplate('./templates/htmlContainer.html', { title: 'History', resourcePath: '../', body });
|
return this.fillTemplate('./templates/htmlContainer.html', {
|
||||||
|
title: 'History',
|
||||||
|
resourcePath: (req.url.substr(-1) === '/' ? '../' : './'),
|
||||||
|
body
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Server.prototype.broadcastVisitors = function () {
|
Server.prototype.broadcastVisitors = function () {
|
||||||
|
@ -261,10 +282,10 @@ Server.prototype.addBook = function (uploadData = {}, success = () => {}, error
|
||||||
const bookPath = path.resolve(this.fileLocation, bookId);
|
const bookPath = path.resolve(this.fileLocation, bookId);
|
||||||
|
|
||||||
const bookData = {
|
const bookData = {
|
||||||
title: uploadData.title.trim(),
|
title: striptags(uploadData.title.trim()),
|
||||||
author: uploadData.author.trim(),
|
author: striptags(uploadData.author.trim()),
|
||||||
summary: uploadData.summary.trim(),
|
summary: striptags(uploadData.summary.trim().replace(/\r\n/g, '\n')),
|
||||||
contributor: uploadData.contributor.trim(),
|
contributor: striptags(uploadData.contributor.trim()),
|
||||||
added: Date.now(),
|
added: Date.now(),
|
||||||
fileType: book.name.substr(book.name.lastIndexOf('.')),
|
fileType: book.name.substr(book.name.lastIndexOf('.')),
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
Give
|
Give
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a class="navbar-item" href="/history/">
|
<a class="navbar-item" href="/history">
|
||||||
History
|
History
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
{{siteTitle}} is a digital give a book, take a book website for e-books.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Books that can be diven and are available here are in the following formats:<br>
|
||||||
|
<code>{{allowedFormats}}</code><br>
|
||||||
|
with {{maxFileSize}} maximum file size.
|
||||||
|
</p>
|
||||||
|
</div>
|
|
@ -1,4 +1,4 @@
|
||||||
<form action="./give" method="post" enctype="multipart/form-data">
|
<form action="{{resourcePath}}give" method="post" enctype="multipart/form-data">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="title">Book Title:</label>
|
<label class="label" for="title">Book Title:</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
|
|
|
@ -778,6 +778,11 @@ strip-outer@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
escape-string-regexp "^1.0.2"
|
escape-string-regexp "^1.0.2"
|
||||||
|
|
||||||
|
striptags@^3.1.1:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.1.1.tgz#c8c3e7fdd6fb4bb3a32a3b752e5b5e3e38093ebd"
|
||||||
|
integrity sha1-yMPn/db7S7OjKjt1LltePjgJPr0=
|
||||||
|
|
||||||
to-array@0.1.4:
|
to-array@0.1.4:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
|
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
|
||||||
|
|
Loading…
Reference in New Issue