the reminder not showing content on the card at dashboard view and the quizes are hardcoded must move to the db make api's for it
210 lines
4.4 KiB
JavaScript
210 lines
4.4 KiB
JavaScript
/*!
|
|
* serve-static
|
|
* Copyright(c) 2010 Sencha Inc.
|
|
* Copyright(c) 2011 TJ Holowaychuk
|
|
* Copyright(c) 2014-2016 Douglas Christopher Wilson
|
|
* MIT Licensed
|
|
*/
|
|
|
|
'use strict'
|
|
|
|
/**
|
|
* Module dependencies.
|
|
* @private
|
|
*/
|
|
|
|
var encodeUrl = require('encodeurl')
|
|
var escapeHtml = require('escape-html')
|
|
var parseUrl = require('parseurl')
|
|
var resolve = require('path').resolve
|
|
var send = require('send')
|
|
var url = require('url')
|
|
|
|
/**
|
|
* Module exports.
|
|
* @public
|
|
*/
|
|
|
|
module.exports = serveStatic
|
|
module.exports.mime = send.mime
|
|
|
|
/**
|
|
* @param {string} root
|
|
* @param {object} [options]
|
|
* @return {function}
|
|
* @public
|
|
*/
|
|
|
|
function serveStatic (root, options) {
|
|
if (!root) {
|
|
throw new TypeError('root path required')
|
|
}
|
|
|
|
if (typeof root !== 'string') {
|
|
throw new TypeError('root path must be a string')
|
|
}
|
|
|
|
// copy options object
|
|
var opts = Object.create(options || null)
|
|
|
|
// fall-though
|
|
var fallthrough = opts.fallthrough !== false
|
|
|
|
// default redirect
|
|
var redirect = opts.redirect !== false
|
|
|
|
// headers listener
|
|
var setHeaders = opts.setHeaders
|
|
|
|
if (setHeaders && typeof setHeaders !== 'function') {
|
|
throw new TypeError('option setHeaders must be function')
|
|
}
|
|
|
|
// setup options for send
|
|
opts.maxage = opts.maxage || opts.maxAge || 0
|
|
opts.root = resolve(root)
|
|
|
|
// construct directory listener
|
|
var onDirectory = redirect
|
|
? createRedirectDirectoryListener()
|
|
: createNotFoundDirectoryListener()
|
|
|
|
return function serveStatic (req, res, next) {
|
|
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
if (fallthrough) {
|
|
return next()
|
|
}
|
|
|
|
// method not allowed
|
|
res.statusCode = 405
|
|
res.setHeader('Allow', 'GET, HEAD')
|
|
res.setHeader('Content-Length', '0')
|
|
res.end()
|
|
return
|
|
}
|
|
|
|
var forwardError = !fallthrough
|
|
var originalUrl = parseUrl.original(req)
|
|
var path = parseUrl(req).pathname
|
|
|
|
// make sure redirect occurs at mount
|
|
if (path === '/' && originalUrl.pathname.substr(-1) !== '/') {
|
|
path = ''
|
|
}
|
|
|
|
// create send stream
|
|
var stream = send(req, path, opts)
|
|
|
|
// add directory handler
|
|
stream.on('directory', onDirectory)
|
|
|
|
// add headers listener
|
|
if (setHeaders) {
|
|
stream.on('headers', setHeaders)
|
|
}
|
|
|
|
// add file listener for fallthrough
|
|
if (fallthrough) {
|
|
stream.on('file', function onFile () {
|
|
// once file is determined, always forward error
|
|
forwardError = true
|
|
})
|
|
}
|
|
|
|
// forward errors
|
|
stream.on('error', function error (err) {
|
|
if (forwardError || !(err.statusCode < 500)) {
|
|
next(err)
|
|
return
|
|
}
|
|
|
|
next()
|
|
})
|
|
|
|
// pipe
|
|
stream.pipe(res)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Collapse all leading slashes into a single slash
|
|
* @private
|
|
*/
|
|
function collapseLeadingSlashes (str) {
|
|
for (var i = 0; i < str.length; i++) {
|
|
if (str.charCodeAt(i) !== 0x2f /* / */) {
|
|
break
|
|
}
|
|
}
|
|
|
|
return i > 1
|
|
? '/' + str.substr(i)
|
|
: str
|
|
}
|
|
|
|
/**
|
|
* Create a minimal HTML document.
|
|
*
|
|
* @param {string} title
|
|
* @param {string} body
|
|
* @private
|
|
*/
|
|
|
|
function createHtmlDocument (title, body) {
|
|
return '<!DOCTYPE html>\n' +
|
|
'<html lang="en">\n' +
|
|
'<head>\n' +
|
|
'<meta charset="utf-8">\n' +
|
|
'<title>' + title + '</title>\n' +
|
|
'</head>\n' +
|
|
'<body>\n' +
|
|
'<pre>' + body + '</pre>\n' +
|
|
'</body>\n' +
|
|
'</html>\n'
|
|
}
|
|
|
|
/**
|
|
* Create a directory listener that just 404s.
|
|
* @private
|
|
*/
|
|
|
|
function createNotFoundDirectoryListener () {
|
|
return function notFound () {
|
|
this.error(404)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a directory listener that performs a redirect.
|
|
* @private
|
|
*/
|
|
|
|
function createRedirectDirectoryListener () {
|
|
return function redirect (res) {
|
|
if (this.hasTrailingSlash()) {
|
|
this.error(404)
|
|
return
|
|
}
|
|
|
|
// get original URL
|
|
var originalUrl = parseUrl.original(this.req)
|
|
|
|
// append trailing slash
|
|
originalUrl.path = null
|
|
originalUrl.pathname = collapseLeadingSlashes(originalUrl.pathname + '/')
|
|
|
|
// reformat the URL
|
|
var loc = encodeUrl(url.format(originalUrl))
|
|
var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + escapeHtml(loc))
|
|
|
|
// send redirect response
|
|
res.statusCode = 301
|
|
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
|
|
res.setHeader('Content-Length', Buffer.byteLength(doc))
|
|
res.setHeader('Content-Security-Policy', "default-src 'none'")
|
|
res.setHeader('X-Content-Type-Options', 'nosniff')
|
|
res.setHeader('Location', loc)
|
|
res.end(doc)
|
|
}
|
|
}
|