First commit
This commit is contained in:
560
framework/server/serverManager.js
Normal file
560
framework/server/serverManager.js
Normal file
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020, 2023, The Unified Company.
|
||||
|
||||
This code is part of Unify.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
|
||||
as published by the ESA.
|
||||
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
|
||||
|
||||
https://unifyjs.org
|
||||
|
||||
*/
|
||||
|
||||
//import compression from 'compression';
|
||||
|
||||
//import express from 'express';
|
||||
|
||||
//import nocache from 'nocache';
|
||||
|
||||
//import cors from "cors";
|
||||
|
||||
//import bodyParser from 'body-parser';
|
||||
|
||||
//import { RateLimiterMemory } from 'rate-limiter-flexible';
|
||||
|
||||
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import https from 'https';
|
||||
|
||||
import http from 'http';
|
||||
|
||||
import fs from "fs";
|
||||
|
||||
import tools from '../unify/tools.js';
|
||||
|
||||
import Console from './console.js';
|
||||
|
||||
import database from './database.js';
|
||||
|
||||
import querySQL from '../unify/querySQL.js';
|
||||
|
||||
import mimeLookup from "../../assets/json/mimeTypes.json" assert { type: "json" };
|
||||
|
||||
|
||||
|
||||
export default class serverManager{
|
||||
|
||||
__className = "serverManager";
|
||||
|
||||
mode;
|
||||
|
||||
port = 8070;
|
||||
|
||||
ssl = false;
|
||||
|
||||
httpsServer = false;
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
//this.initializeRateLimiter();
|
||||
|
||||
}
|
||||
|
||||
createExpressApp() {
|
||||
|
||||
//this.app = express();
|
||||
|
||||
}
|
||||
|
||||
createHttpsServer( ) {
|
||||
|
||||
if( this.ssl ) {
|
||||
|
||||
var privateKey = fs.readFileSync('./sslCertificates/privkey.pem', 'utf8');
|
||||
|
||||
var certificate = fs.readFileSync('./sslCertificates/fullchain.pem', 'utf8');
|
||||
|
||||
this.httpsServer = https.createServer({ key: privateKey, cert: certificate }, this.app );
|
||||
|
||||
} else {
|
||||
|
||||
this.httpsServer = http.createServer( this.app );
|
||||
|
||||
}
|
||||
|
||||
return this.httpsServer;
|
||||
|
||||
}
|
||||
|
||||
createListener( ) {
|
||||
|
||||
if( this.ssl ) {
|
||||
|
||||
if( !this.port ) {
|
||||
|
||||
this.port = 443;
|
||||
|
||||
}
|
||||
|
||||
this.httpsServer.listen( this.port );
|
||||
|
||||
console.log("\nHttps WebServer started on port: ", this.port);
|
||||
|
||||
} else {
|
||||
|
||||
this.httpsServer.listen( this.port );
|
||||
|
||||
console.log("\nHttps WebServer started on port: ", 443);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
initializeRateLimiter() {
|
||||
|
||||
this.rateLimiter = new RateLimiterMemory({
|
||||
|
||||
points: 1000,
|
||||
duration: 1,
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
restrictDirectories( app ) {
|
||||
|
||||
app.all('/sslCertificates/*', function (req,res, next) {
|
||||
|
||||
res.status(403).send({
|
||||
|
||||
message: 'Access Forbidden'
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
app.all('/storage/*', function (req,res, next) {
|
||||
|
||||
res.status(403).send({
|
||||
|
||||
message: 'Access Forbidden'
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
exposeDirectories( app ) {
|
||||
|
||||
app.use( express.static( path.resolve("") ) );
|
||||
|
||||
|
||||
if( global.mode == "production" ) {
|
||||
|
||||
app.use( express.static( path.resolve( 'assets/production/') ) );
|
||||
|
||||
} else {
|
||||
|
||||
app.use( express.static( path.resolve( 'assets/development/') ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
app.use( express.static( path.resolve('application/') ) );
|
||||
|
||||
app.use( express.static( path.resolve('admin/') ) );
|
||||
|
||||
app.use( express.static( path.resolve('framework/') , { maxAge: 99999999999 } ) );
|
||||
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
app.use( "/*.html", function ( req, res ) {
|
||||
|
||||
res.sendFile( path.resolve('assets/development/index.html') );//
|
||||
|
||||
} );
|
||||
|
||||
} else {
|
||||
|
||||
app.use( "/*.html", function ( req, res ) {
|
||||
|
||||
res.sendFile( path.resolve( 'assets/production/index.html') );
|
||||
|
||||
});
|
||||
|
||||
app.use( "/*.json", function ( req, res ) {
|
||||
|
||||
res.sendFile( path.resolve( 'assets/production/index.json') );
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async rateLimiterCallback( req, res, next ) {
|
||||
|
||||
var rate = await this.rateLimiter.consume( this.userID, 2 )
|
||||
.then( () => {
|
||||
|
||||
return true;
|
||||
|
||||
})
|
||||
.catch( () => {
|
||||
|
||||
return false;
|
||||
|
||||
});
|
||||
|
||||
if( !rate ) {
|
||||
|
||||
res.writeHead( 429 );
|
||||
|
||||
res.end();
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if( next ) {
|
||||
|
||||
next();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
usePlugins( app ) {
|
||||
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
app.use( nocache() );
|
||||
|
||||
}
|
||||
|
||||
app.use( cors() );
|
||||
|
||||
app.use( bodyParser.json() );
|
||||
|
||||
app.use( compression() );
|
||||
|
||||
app.use( async ( req, res, next ) => {
|
||||
|
||||
this.rateLimiterCallback( req, res, next );
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
getExtension(filename) {
|
||||
|
||||
var ext = path.extname( filename || '' ).split('.');
|
||||
|
||||
return "." + ext[ext.length - 1];
|
||||
|
||||
}
|
||||
|
||||
setupServer() {
|
||||
|
||||
//var app = this.app;
|
||||
|
||||
|
||||
//this.usePlugins( app );
|
||||
|
||||
//this.restrictDirectories( app );
|
||||
|
||||
//this.exposeDirectories( app );
|
||||
|
||||
|
||||
//https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
||||
/*
|
||||
const mimeLookup = {
|
||||
|
||||
'.js': 'application/javascript',
|
||||
|
||||
'.html': 'text/html',
|
||||
|
||||
'.css':'text/css',
|
||||
|
||||
'.woff':'font/woff',
|
||||
|
||||
'.woff2':'font/woff2',
|
||||
|
||||
'.ttf':'font/ttf',
|
||||
|
||||
'.png':'png'
|
||||
};
|
||||
*/
|
||||
|
||||
function send404(response){
|
||||
|
||||
response.writeHead(404, {'Content-Type': 'text/plain'});
|
||||
|
||||
response.write('Error 404: Resource not found.');
|
||||
|
||||
response.end();
|
||||
|
||||
}
|
||||
|
||||
var that = this;
|
||||
|
||||
/*
|
||||
|
||||
http.createServer( function( req, res ) {
|
||||
|
||||
if( req.method == 'GET' ) {
|
||||
|
||||
let fileurl;
|
||||
|
||||
var cleanUrl = req.url.split("?")[0];
|
||||
|
||||
var fileExt = that.getExtension( cleanUrl );
|
||||
|
||||
var mimeType = mimeLookup[ fileExt ];
|
||||
|
||||
//console.log("req.url", req.url);
|
||||
|
||||
//console.log("fileExt", fileExt);
|
||||
|
||||
|
||||
|
||||
if( mimeType == 'text/html' || fileExt == '.' ) {
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
fileurl = '/assets/development/index.html';
|
||||
|
||||
} else {
|
||||
|
||||
fileurl = '/assets/production/index.html';
|
||||
|
||||
}
|
||||
|
||||
mimeType = "text/html";
|
||||
|
||||
} else {
|
||||
|
||||
if( !mimeType ) {
|
||||
|
||||
send404(res);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
fileurl = cleanUrl;
|
||||
|
||||
}
|
||||
|
||||
var filepath = path.resolve('./' + fileurl);
|
||||
|
||||
fs.exists( filepath, ( exists ) => {
|
||||
|
||||
if( !exists ) {
|
||||
|
||||
send404(res);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
res.writeHead( 200, {'Content-Type': mimeType } );
|
||||
|
||||
fs.createReadStream( filepath ).pipe( res );
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}).listen( 3000 );
|
||||
*/
|
||||
|
||||
var reject = new Array();
|
||||
|
||||
|
||||
reject.push( "/framework/cache/platforms/Original/" );
|
||||
|
||||
reject.push( "/framework/cache/platforms/Server/" );
|
||||
|
||||
reject.push( "/framework/cache/server/" );
|
||||
|
||||
reject.push( "/storage/" );
|
||||
|
||||
reject.push( "/application/" );
|
||||
|
||||
reject.push( "package.json" );
|
||||
|
||||
var server = this;
|
||||
|
||||
|
||||
this.app = function( req, res ) {
|
||||
|
||||
//res.setHeader("Content-Security-Policy", "default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests");
|
||||
|
||||
//res.setHeader("Content-Security-Policy", "default-src 'self' ws: wss: " + server.serverAddress + " *." + server.serverAddress + "style-src 'self' 'unsafe-inline';" );
|
||||
|
||||
if( req.method == 'GET' ) {
|
||||
|
||||
let fileurl;
|
||||
|
||||
var cleanUrl = req.url.split("?")[0];
|
||||
|
||||
var fileExt = that.getExtension( cleanUrl );
|
||||
|
||||
var mimeType = mimeLookup[ fileExt ];
|
||||
|
||||
|
||||
if( mimeType == 'text/html' || fileExt == '.' || fileExt == '.html' || fileExt == '.htm' ) {
|
||||
|
||||
if( global.mode == "development" ) {
|
||||
|
||||
fileurl = '/assets/development/index.html';
|
||||
|
||||
} else {
|
||||
|
||||
fileurl = '/assets/production/index.html';
|
||||
|
||||
}
|
||||
|
||||
mimeType = "text/html";
|
||||
|
||||
} else {
|
||||
|
||||
//if( !mimeType ) {
|
||||
|
||||
// send404(res);
|
||||
|
||||
// return;
|
||||
|
||||
//}
|
||||
|
||||
fileurl = cleanUrl;
|
||||
|
||||
}
|
||||
|
||||
//console.log(fileurl);
|
||||
|
||||
for (var i = 0; i < reject.length; i++) {
|
||||
|
||||
var rejectURl = reject[i];
|
||||
|
||||
|
||||
if( fileurl.includes( rejectURl ) ) {
|
||||
|
||||
console.log("Access forbidden, reject url.");
|
||||
|
||||
send404( res );
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var filepath = path.resolve('./' + fileurl);
|
||||
|
||||
fs.exists( filepath, ( exists ) => {
|
||||
|
||||
if( !exists ) {
|
||||
|
||||
send404(res);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//console.log(fileurl, mimeType);
|
||||
|
||||
res.writeHead( 200, {'Content-Type': mimeType } );
|
||||
|
||||
fs.createReadStream( filepath ).pipe( res );
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//.listen( 3000 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
secureStatic( secure ) {
|
||||
|
||||
return function ( req, res, next ) {
|
||||
|
||||
var result = req.url.match(/^\/framework\/db\/.+$/);
|
||||
|
||||
if ( result ) {
|
||||
|
||||
return res.status(403).end('403 Forbidden')
|
||||
|
||||
} else {
|
||||
|
||||
next();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
runAPIServer() {
|
||||
|
||||
/*
|
||||
var app = this.app;
|
||||
|
||||
var that = this;
|
||||
|
||||
|
||||
app.use( "/api/", function ( req, res ) {
|
||||
|
||||
const body = JSON.stringify( req.body );
|
||||
|
||||
class ajaxSocket{
|
||||
|
||||
send( content ) {
|
||||
|
||||
|
||||
res.json( content );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( req.body.eventName == "connect" ) {
|
||||
|
||||
that.socketManager.connection( new ajaxSocket() );
|
||||
|
||||
} else {
|
||||
|
||||
var object = JSON.parse( body );
|
||||
|
||||
var clients = that.socketManager.sessionClients;
|
||||
|
||||
var client = clients[object.sessionKey];
|
||||
|
||||
client.socket.send = function( content ) {
|
||||
|
||||
res.json( content );
|
||||
|
||||
}
|
||||
|
||||
client.message( body );
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user