@blaasvaer/frmwrk
Version:
My personal Node framework
177 lines (156 loc) • 5.39 kB
JavaScript
'use strict';
const fs = require('fs');
const path = require('path');
const statics = require('serve-handler');
const { findRoute } = require('./router');
const content_types = {
"text" : 'text/plain; charset=utf-8',
"html" : 'text/html; charset=utf-8',
"json" : 'application/json; charset=utf-8'
};
/**
* Handle incoming request
* @param {Object} req The incoming request object
* @param {Object} res The response object
* @return {Object} Return the response
*/
async function handleRequest( req, res ) {
let method = req.method;
// console.log("handleRequest, req", req );
const request_url = new URL( req.url, `http://${req.headers.host}`);
// console.log("handleRequest, request_url", request_url);
// console.log("handleRequest, request_url.searchParams", request_url.searchParams);
/**
* Set default status and header
* @type {Number}
*/
let status_code = 200;
let content_type = 'html';
// Prevent errors from missing favicon
if (request_url.pathname === '/favicon.ico') {
// TODO: Set theme dynamically
var favicon = path.join('assets/favicon', 'favicon.ico');
res.statusCode = 200;
res.setHeader('Content-Type', 'image/x-icon');
if ( fs.existsSync( favicon ) ) {
fs.createReadStream( favicon ).pipe( res );
return;
} else {
return;
}
}
/**
* Service Worker from root
*/
if (request_url.pathname === '/service-worker.js') {
// TODO: Set theme dynamically
var worker = path.join('', 'service-worker.js');
res.statusCode = 200;
res.setHeader('Content-Type', 'text/javascript');
if ( fs.existsSync( worker ) ) {
fs.createReadStream( worker ).pipe( res );
return;
} else {
return;
}
}
/**
* Find route in Router based on url
*/
const route = findRoute( request_url );
/**
* Check for complete route
* @param {[type]} route [description]
* @return {[type]} [description]
*/
if ( route ) {
/**
* Create new controller from route
*/
const controller = new Controller( route, req, res, request_url );
let response_output = 'Nothing here …';
/**
* Set Content Type
*/
if ( controller?.route?.params?.type ) {
content_type = controller?.route?.params?.type;
}
switch ( method ) {
case 'GET':
if ( ! controller.route.params?.authorize ) {
/**
* If the route has no parameters, then just run the route method and serve whatever it may …
*/
response_output = await controller.view();
} else {
/**
* Authorization
*/
if ( Authorize( controller.route ) ) {
// console.log(`We're authorized!`, controller.route.params);
response_output = await controller.view();
} else {
// console.log(`We're NOT authorized!`, controller.route.params);
/**
* Redirect the user to login if auth fails
*/
if ( controller.route.params.authorize.redirect ) {
// console.log('controller.route.params.redirect', controller.route.params.redirect);
status_code = 302;
res.setHeader( 'Location', controller.route.params.authorize.redirect );
}
// console.log("NO USER", controller.route.params.redirect);
// response_output = redirect.action.call();
// route.params.redirect.call();
// response_output = 'Access denied';
}
}
res.statusCode = status_code;
res.setHeader( 'Content-Type', content_types[content_type] );
res.setHeader( 'Access-Control-Allow-Origin', 'http://localhost');
res.setHeader( 'Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
// res.setHeader( 'Content-Security-Policy', "default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; frame-src 'self'");
// res.setHeader( 'Content-Security-Policy', "default-src 'self'; img-src 'self';");
// Cookies
res.setHeader('Set-Cookie','uuid=1234-1324-1234-1234-1234; Max-Age=3000; SameSite=lax; Secure');
// Set a same-site cookie for first-party contexts
// res.cookie('cookie1', 'value1', { sameSite: 'lax' });
// Set a cross-site cookie for third-party contexts
// res.cookie('cookie2', 'value2', { sameSite: 'none', secure: true });
res.end( response_output );
break;
case 'POST':
case 'PUT':
case 'PATCH':
case 'UPDATE':
let data = '';
req.on('data', chunk => {
data += chunk;
})
req.on('end', async () => {
res.statusCode = status_code;
res.setHeader( 'Content-Type', content_types[content_type] );
// Cookies
// res.setHeader( 'Set-Cookie','uuid=1234-1324-1234-1234-1234; Max-Age=3000; SameSite=lax; Secure' );
res.setHeader( 'Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE, OPTIONS' );
// res.setHeader( 'Content-Security-Policy', "default-src 'self'; img-src 'self';");
response_output = await controller.view( data );
res.end( response_output );
})
break;
}
} else if ( request_url.pathname.split('/')[1] == 'assets' ) {
/**
* Serve static files from public directory
*/
statics( req, res, {
public: 'public'
} );
return;
} else {
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain; charset=utf-8' );
res.end("404 – Page not found: " + request_url + ".\n\nDo you have a controller with an action for that route?");
}
}
module.exports = handleRequest;