* When gitHash in config.js is set to true, latest commit hash of the currently enabled git repo/branch will be displayed in home and nojs uploader pages.

* Error pages can now be configured with errorPages option (their root directory and their file names).
This commit is contained in:
Bobby Wibowo 2018-09-20 18:41:17 +07:00
parent d875a604be
commit 0d38995b2b
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
8 changed files with 88 additions and 21 deletions

View File

@ -71,6 +71,21 @@ module.exports = {
'.profile'
],
/*
Show hash of the current git commit in homepage.
*/
showGitHash: false,
/*
Path to error pages. Only 404 and 500 will be used.
Note: rootDir can either be relative or absolute path.
*/
errorPages: {
rootDir: './pages/error',
404: '404.html',
500: '500.html'
},
/*
Uploads config.
*/

View File

@ -12,6 +12,14 @@ const nunjucks = require('nunjucks')
const RateLimit = require('express-rate-limit')
const safe = express()
// It appears to be best to catch these before doing anything else
process.on('uncaughtException', error => {
console.error('Uncaught Exception:', error)
})
process.on('unhandledRejection', error => {
console.error('Unhandled Rejection (Promise):', error)
})
require('./database/db.js')(db)
fs.existsSync('./pages/custom') || fs.mkdirSync('./pages/custom')
@ -60,7 +68,8 @@ for (const page of config.pages) {
}))
} else if (page === 'home') {
safe.get('/', (req, res, next) => res.render('home', {
urlMaxSize: config.uploads.urlMaxSize
urlMaxSize: config.uploads.urlMaxSize,
gitHash: safe.get('git-hash')
}))
} else if (page === 'faq') {
const fileLength = config.uploads.fileLength
@ -78,33 +87,37 @@ for (const page of config.pages) {
}
safe.use((req, res, next) => {
res.status(404).sendFile('404.html', { root: './pages/error/' })
res.status(404).sendFile(config.errorPages[404], { root: config.errorPages.rootDir })
})
safe.use((error, req, res, next) => {
console.error(error)
res.status(500).sendFile('500.html', { root: './pages/error/' })
})
process.on('uncaughtException', error => {
console.error('Uncaught Exception:', error)
})
process.on('unhandledRejection', error => {
console.error('Unhandled Rejection (Promise):', error)
res.status(500).sendFile(config.errorPages[500], { root: config.errorPages.rootDir })
})
const start = async () => {
if (config.showGitHash) {
const gitHash = await new Promise((resolve, reject) => {
require('child_process').exec('git rev-parse HEAD', (error, stdout) => {
if (error) { return reject(error) }
resolve(stdout.replace(/\n$/, ''))
})
}).catch(console.error)
if (!gitHash) { return }
console.log(`Git commit: ${gitHash}`)
safe.set('git-hash', gitHash)
}
if (config.uploads.scan && config.uploads.scan.enabled) {
const created = await new Promise(async (resolve, reject) => {
if (!config.uploads.scan.ip || !config.uploads.scan.port) {
return reject(new Error('Clamd IP or Port is missing'))
return reject(new Error('clamd IP or port is missing'))
}
const ping = await clamd.ping(config.uploads.scan.ip, config.uploads.scan.port).catch(reject)
if (!ping) {
return reject(new Error('Could not ping clamd'))
}
const version = await clamd.version(config.uploads.scan.ip, config.uploads.scan.port).catch(reject)
console.log(`${config.uploads.scan.ip}:${config.uploads.scan.port} ${version}`)
console.log(`${config.uploads.scan.ip}:${config.uploads.scan.port} ${version}`)
const scanner = clamd.createScanner(config.uploads.scan.ip, config.uploads.scan.port)
safe.set('clam-scanner', scanner)
return resolve(true)

View File

@ -1 +0,0 @@
../../../HttpErrorPages/dist/HTTP404.html

17
pages/error/404.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Simple HttpErrorPages | MIT License | https://github.com/AndiDittrich/HttpErrorPages -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>We've got some trouble | 404 - Resource not found</title>
<style type="text/css">@font-face{font-family:Lato;font-style:normal;font-weight:400;src:url(//fiery.me/fonts/lato/lato-v14-latin-regular.eot);src:local('Lato Regular'),local('Lato-Regular'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.eot?#iefix) format('embedded-opentype'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.woff2) format('woff2'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.woff) format('woff'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.ttf) format('truetype'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.svg#Lato) format('svg')}/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}/*! Simple HttpErrorPages | MIT X11 License | https://github.com/AndiDittrich/HttpErrorPages */body,html{width:100%;height:100%;background-color:#232629}body{color:#eff0f1;text-align:center;padding:0;min-height:100%;display:table;font-family:Lato}h1{font-family:inherit;font-weight:500;line-height:1.1;color:inherit;font-size:36px}h1 small{font-size:68%;font-weight:400;line-height:1;color:#bdc3c7}a{text-decoration:none;color:#3794d2;font-size:inherit;border-bottom:dotted 1px #3794d2}a:active,a:focus,a:hover{color:#60a8dc;border-bottom-color:#60a8dc}.lead{color:silver;font-size:21px;line-height:1.4}.cover{display:table-cell;vertical-align:middle;padding:0 20px}footer{position:fixed;width:100%;height:40px;left:0;bottom:0;color:#bdc3c7;font-size:14px}</style>
</head>
<body>
<div class="cover">
<h1>Resource not found <small>404</small></h1>
<p class="lead">The requested resource could not be found but may be available again in the future.</p>
</div>
</body>
</html>

View File

@ -1 +0,0 @@
../../../HttpErrorPages/dist/HTTP500.html

17
pages/error/500.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Simple HttpErrorPages | MIT License | https://github.com/AndiDittrich/HttpErrorPages -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>We've got some trouble | 500 - Webservice currently unavailable</title>
<style type="text/css">@font-face{font-family:Lato;font-style:normal;font-weight:400;src:url(//fiery.me/fonts/lato/lato-v14-latin-regular.eot);src:local('Lato Regular'),local('Lato-Regular'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.eot?#iefix) format('embedded-opentype'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.woff2) format('woff2'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.woff) format('woff'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.ttf) format('truetype'),url(//fiery.me/fonts/lato/lato-v14-latin-regular.svg#Lato) format('svg')}/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}/*! Simple HttpErrorPages | MIT X11 License | https://github.com/AndiDittrich/HttpErrorPages */body,html{width:100%;height:100%;background-color:#232629}body{color:#eff0f1;text-align:center;padding:0;min-height:100%;display:table;font-family:Lato}h1{font-family:inherit;font-weight:500;line-height:1.1;color:inherit;font-size:36px}h1 small{font-size:68%;font-weight:400;line-height:1;color:#bdc3c7}a{text-decoration:none;color:#3794d2;font-size:inherit;border-bottom:dotted 1px #3794d2}a:active,a:focus,a:hover{color:#60a8dc;border-bottom-color:#60a8dc}.lead{color:silver;font-size:21px;line-height:1.4}.cover{display:table-cell;vertical-align:middle;padding:0 20px}footer{position:fixed;width:100%;height:40px;left:0;bottom:0;color:#bdc3c7;font-size:14px}</style>
</head>
<body>
<div class="cover">
<h1>Webservice currently unavailable <small>500</small></h1>
<p class="lead">An unexpected condition was encountered.<br>Our service team has been dispatched to bring it back online.</p>
</div>
</body>
</html>

View File

@ -1,5 +0,0 @@
# Disclaimer as to why this folder only have Symlinks
At fiery.me, we are using this: [https://github.com/BobbyWibowo/HttpErrorPages](https://github.com/BobbyWibowo/HttpErrorPages).
It's nothing too important, but we are sharing the error pages from that directory to all other instances in the server (regular http sites with nginx and node servers).

View File

@ -16,7 +16,10 @@ if (config.private) {
}
routes.get('/nojs', async (req, res, next) => {
return res.render('nojs', { renderOptions })
const options = { renderOptions }
options.gitHash = req.app.get('git-hash')
return res.render('nojs', options)
})
routes.post('/nojs', (req, res, next) => {
@ -26,6 +29,7 @@ routes.post('/nojs', (req, res, next) => {
const result = args[0]
const options = { renderOptions }
options.gitHash = req.app.get('git-hash')
options.errorMessage = result.success ? '' : (result.description || 'An unexpected error occurred.')
options.files = result.files || [{}]

View File

@ -115,6 +115,10 @@
</h3>
{% include "_partial/links.njk" %}
{% if gitHash -%}
<p>Git commit: <a href="https://github.com/BobbyWibowo/lolisafe/commit/{{ gitHash }}" target="_blank" rel="noopener">{{ gitHash }}</a></p>
{%- endif %}
</div>
</div>
</section>

View File

@ -60,6 +60,10 @@
{% set plain_links = true %}
{% include "_partial/links.njk" %}
{% if gitHash -%}
<p>Git commit: <a href="https://github.com/BobbyWibowo/lolisafe/commit/{{ gitHash }}" target="_blank" rel="noopener">{{ gitHash }}</a></p>
{%- endif %}
</div>
</div>
</section>