UNPKG

@blaasvaer/frmwrk

Version:

My personal Node framework

177 lines (156 loc) 5.39 kB
'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;