import {Log} from "fme-logger"; var L = new Log("TradechatServer"); var passport = require('passport'); var browserify = require('browserify-middleware'); browserify.settings.debug = true; var flash = require('connect-flash'); var constants = require('constants'); const session = require('express-session'); const MongoStore = require('connect-mongo')(session); const fileUpload = require('express-fileupload'); export class Keys { key:string = "" cert: string = "" ca: string [] = [] } export class TradechatServerConfig { port:number = 443; pathRoot = "/var/web"; uploadDirectory = "/uploads" name = "default"; master = true; dbUrl = "mongodb://127.0.0.1:27017/test" } import {MongoClient,Db} from "mongodb"; import {TradechatRoomController,TradechatRoom} from "./app/rooms"; import {TradechatUserController, TradechatUser} from "./app/users"; import {FmeUser,StripeId,LiteUser} from "./app/user-models" import {TradechatMessageController,TradechatMessage} from "./app/messages"; //import {Routes} from "./routes/routes"; //import {IoRoutes} from "./routes/io-routes"; import {PollController} from "./polls/poll-chat"; import {TradeChatRosterController} from "./app/roster" import {PassportController} from "./config/passport"; import { TradechatCompanyController,TradechatCompany } from "./app/companies"; import { TradechatEmailController,TradechatEmail } from "./app/email"; import { TradechatProductController,TradechatProduct} from "./app/products" import { TradechatCodeController,TradechatCode} from "./app/codes"; import { TradechatGroupController,TradechatGroup} from "./app/groups"; var mongoose = require('mongoose'); export { TradechatRoomController, TradechatRoom, TradechatUserController, TradechatUser, TradechatMessageController, TradechatMessage, //Routes, //IoRoutes, PollController, TradeChatRosterController, PassportController, FmeUser, TradechatServer, StripeId, LiteUser, TradechatCodeController,TradechatCode, TradechatCompanyController,TradechatCompany, TradechatEmailController, TradechatEmail, TradechatGroupController, TradechatGroup, TradechatProductController, TradechatProduct, } class TradechatServer { version="20.0.0"; production = false; app:any; rooms = new TradechatRoomController(this) users = new TradechatUserController(this); messages = new TradechatMessageController(this); mail = new TradechatEmailController(this); roster = new TradeChatRosterController(this) codes = new TradechatCodeController(this); companies = new TradechatCompanyController(this); groups = new TradechatGroupController(this); products = new TradechatProductController(this); db:Db = {} as Db; io:any; ioOptions = { "force new connection" : true, "reconnection": true, "reconnectionDelay": 2000, //starts with 2 secs delay, then 4, 6, 8, until 60 where it stays forever until it reconnects "reconnectionDelayMax" : 60000, //1 minute maximum delay between connections "reconnectionAttempts": "Infinity", //to prevent dead clients, having the user to having to manually reconnect after a server restart. "timeout" : 10000, //before connect_error and connect_timeout are emitted. "transports" : ["websocket"], //forces the transport to be only websocket. Server needs to be setup as well/ "path": "/chat_server" } constructor(public routes:any,public ioRoutes:any,public poll:PollController, public keys:Keys,public config:TradechatServerConfig) { L.info("=> Booting Tradechat server version",this.version); L.info("Config file is",config) L.info("==> Opened Database"); this.openDatabase(); } init = async () => { this.io = require('socket.io')(this.ioOptions); L.info("===> Init Mail Services"); await this.mail.init(); L.info("=====> Init Users"); await this.users.init(); L.info("====> Init Rooms"); await this.rooms.init(); L.info('======> init codes'); await this.codes.init(); L.info('=======> init products'); await this.products.init(); L.info('========> init companies') await this.companies.init(); L.info("=========> init Messages"); await this.messages.init(); L.info("==========> init Stats"); await this.poll.init(this); L.info("==========> init Roster"); await this.roster.init() L.info("============> init IoRoutes"); await this.ioRoutes.init(this); L.info("===============> init Server") await this.initServer(); L.info("================> init Routes"); await this.routes.init(this); } openDatabase = async() => { L.info("Opening MongoDB Database"); const client = await MongoClient.connect(this.config.dbUrl , { useNewUrlParser: true }) L.info("mongo connected"); var t = await mongoose.connect(this.config.dbUrl, { useNewUrlParser: true, native_parser:true,poolsize:15 }) this.db = client.db() as Db; this.init(); } initServer = async() => { var key = this.keys.key; var cert = this.keys.cert; var ca = this.keys.ca; var https_options = { secureProtocol: 'SSLv23_method', secureOptions: constants.SSL_OP_NO_SSLv3, key: key, cert: cert, ca: ca }; var express = require('express'); var bodyParser = require('body-parser'); var cookieParser = require('cookie-parser'); var methodOverride = require('method-override') this.app = express(); //var server = require('http').Server(app); var server = require('https').createServer(https_options, this.app); this.io.listen(server); var p = new PassportController(this,passport); // // ==> Setup app // //this.app.set('ipaddr', process.env.OPENSHIFT_NODEJS_IP || "107.170.43.245"); this.app.set('port',this.config.port); this.app.set('views', this.config.pathRoot + '/views'); this.app.set('view engine','ejs'); this.app.set('view engine',"pug"); this.app.set('view engine',"jade"); this.app.engine('html', require('ejs').renderFile); this.app.engine('jade', require('jade').__express); this.app.use(cookieParser()); // read cookies (needed for auth) this.app.use(fileUpload()); this.app.use(bodyParser.json({limit:'10mb',extended:true})); this.app.use(bodyParser.urlencoded({limit:'10mb', extended: true })); this.app.use(methodOverride()); this.app.use(session({ // secret: '123fortunesrocksme321', secret: '123fortunesrocksme321', // store: new MongoStore({db:this.db}), store: new MongoStore({ db: 'test', host: '127.0.0.1', port: 27017, autoReconnect: true, mongooseConnection: mongoose.connection }), resave: true, saveUninitialized: true, cookie: { maxage: (1000*60*60*24*7) } })); // session secret this.app.use(passport.initialize()); this.app.use(passport.session()); // persistent login sessions this.app.use(flash()); // use connect-flash for flash messages stored in session this.app.use('/js', express.static(this.config.pathRoot + '/public/js')); this.app.use('/admin/static',express.static(this.config.pathRoot +'/public')); // this.app.use('/client', browserify(__dirname + '/client')); // app.get('/bundle.js', browserify(bundleArray)); this.app.use("/uploads",express.static("/var/uploads")); this.app.use(express.static(this.config.pathRoot + '/public')); this.app.use('/uploads', express.static(this.config.uploadDirectory)); this.app.all('/*', function(req:any, res:any, next:Function) { let fullUrl = req.protocol + '://' + req.get('host'); // console.log("allow access from:",req); // res.header("Access-Control-Allow-Origin", "https://tradechat.me" ); res.header("Access-Control-Allow-Origin", "*" ); res.header("Access-Control-Allow-Headers", "X-Requested-With"); res.header("Access-Control-Allow-Credentials", "true"); next(); }); // Routes ======================================================================== server.listen(this.config.port); }; errorCatchAll = () => { process .on('unhandledRejection', (reason, p) => { L.error(reason, 'Unhandled Rejection at Promise', p); var email = new TradechatEmail(); email.to="support@fortunesrocks.me"; email.from = "info@tradechat.me"; email.html = reason + "
" + p + "
"; email.subject = "Error from server: " + this.config.name; this.mail.send(email); }) .on('uncaughtException', err => { L.error('uncaughtException:',err); var email = new TradechatEmail(); email.to="support@fortunesrocks.me"; email.from = "info@tradechat.me"; email.html = JSON.stringify(err) email.subject = "Error from server: " + this.config.name; this.mail.send(email); }); } }