@resolveio/server-lib 20.3.18 → 20.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkerTaskRequests=void 0;var index_1=require("../index"),mongo_manager_1=require("../managers/mongo.manager"),simpl_schema_1=require("simpl-schema"),schema={_id:{type:String,optional:!0},__v:{type:Number,optional:!0},updatedAt:{type:Date,optional:!0},createdAt:{type:Date,optional:!0},method:{type:String},params:{type:Array},"params.$":{type:simpl_schema_1.default.oneOf(Object,String,Number,Boolean,Date),blackbox:!0},status:{type:String},id_user:{type:String},user:{type:String},id_ws:{type:String}};function initializeCollection(){var e;index_1.ResolveIOServer&&index_1.ResolveIOServer.getMainDB()?(e=new mongo_manager_1.MongoManagerModel({collectionName:"worker-task-requests",schema:schema,useVersionCollection:!1,useReportBuilder:!1,reportBuilderLookupTables:[],timestamps:!0,createLogs:!1,checkSchema:!1,collectionOptions:null}),exports.WorkerTaskRequests=e.collection_main,exports.WorkerTaskRequests.createIndex({createdAt:1},{expireAfterSeconds:7776e3}),exports.WorkerTaskRequests.createIndex({status:1,createdAt:1})):setTimeout(function(){initializeCollection()},0)}exports.WorkerTaskRequests=null,initializeCollection();
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkerTaskRequests=void 0;var index_1=require("../index"),mongo_manager_1=require("../managers/mongo.manager"),simpl_schema_1=require("simpl-schema"),schema={_id:{type:String,optional:!0},__v:{type:Number,optional:!0},updatedAt:{type:Date,optional:!0},createdAt:{type:Date,optional:!0},method:{type:String},params:{type:Array},"params.$":{type:simpl_schema_1.default.oneOf(Object,String,Number,Boolean,Date),blackbox:!0},status:{type:String},id_user:{type:String},user:{type:String},id_ws:{type:String}};function initializeCollection(){var e;index_1.ResolveIOServer&&index_1.ResolveIOServer.getMainDB()?(e=new mongo_manager_1.MongoManagerModel({collectionName:"worker-task-requests",schema:schema,useVersionCollection:!1,useReportBuilder:!1,reportBuilderLookupTables:[],timestamps:!0,createLogs:!1,checkSchema:!1,collectionOptions:null}),exports.WorkerTaskRequests=e.collection_main,exports.WorkerTaskRequests.createIndex({createdAt:1},{expireAfterSeconds:7776e3}),exports.WorkerTaskRequests.createIndex({status:1,createdAt:1}),exports.WorkerTaskRequests.createIndex({_id:1,status:1})):setTimeout(function(){initializeCollection()},0)}exports.WorkerTaskRequests=null,initializeCollection();
2
2
  //# sourceMappingURL=worker-task-request.collection.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/collections/worker-task-request.collection.ts"],"names":["index_1","require","mongo_manager_1","simpl_schema_1","schema","_id","type","String","optional","__v","Number","updatedAt","Date","createdAt","method","params","Array","params.$","default","oneOf","Object","Boolean","blackbox","status","id_user","user","id_ws","initializeCollection","model","ResolveIOServer","getMainDB","MongoManagerModel","collectionName","useVersionCollection","useReportBuilder","reportBuilderLookupTables","timestamps","createLogs","checkSchema","collectionOptions","exports","WorkerTaskRequests","collection_main","createIndex","expireAfterSeconds","setTimeout"],"mappings":"sGACA,IAAAA,QAAAC,QAAA,UAAA,EACAC,gBAAAD,QAAA,2BAAA,EACAE,eAAAF,QAAA,cAAA,EAEIG,OAAc,CACjBC,IAAK,CACJC,KAAMC,OACNC,SAAU,CAAA,C,EAEXC,IAAK,CACJH,KAAMI,OACNF,SAAU,CAAA,C,EAEXG,UAAW,CACVL,KAAMM,KACNJ,SAAU,CAAA,C,EAEXK,UAAW,CACVP,KAAMM,KACNJ,SAAU,CAAA,C,EAEXM,OAAQ,CACPR,KAAMC,M,EAEPQ,OAAQ,CACPT,KAAMU,K,EAEPC,WAAY,CACXX,KAAMH,eAAAe,QAAaC,MAAMC,OAAQb,OAAQG,OAAQW,QAAST,IAAI,EAC9DU,SAAU,CAAA,C,EAEXC,OAAQ,CACPjB,KAAMC,M,EAEPiB,QAAS,CACRlB,KAAMC,M,EAEPkB,KAAM,CACLnB,KAAMC,M,EAEPmB,MAAO,CACNpB,KAAMC,M,GAQR,SAASoB,uBACR,IACOC,EADH5B,QAAA6B,iBAAmB7B,QAAA6B,gBAAgBC,UAAS,GACzCF,EAAQ,IAAI1B,gBAAA6B,kBAA0C,CAC3DC,eAAgB,uBAChB5B,OAAQA,OACR6B,qBAAsB,CAAA,EACtBC,iBAAkB,CAAA,EAClBC,0BAA2B,GAC3BC,WAAY,CAAA,EACZC,WAAY,CAAA,EACZC,YAAa,CAAA,EACbC,kBAAmB,I,CACnB,EACDC,QAAAC,mBAAqBb,EAAMc,gBAC3BF,QAAAC,mBAAmBE,YAAY,CAAC9B,UAAW,CAAC,EAAG,CAAC+B,mBAAoB,MAAiB,CAAC,EACtFJ,QAAAC,mBAAmBE,YAAY,CAACpB,OAAQ,EAAGV,UAAW,CAAC,CAAC,GAGxDgC,WAAW,WACVlB,qBAAoB,CACrB,EAAG,CAAC,CAEN,CA1BWa,QAAAC,mBAAqE,KAEhFd,qBAAoB","file":"worker-task-request.collection.js","sourcesContent":["import { WorkerTaskRequestModel } from '../models/worker-task-request.model';\nimport { ResolveIOServer } from '../index';\nimport { MongoManagerCollection, MongoManagerModel } from '../managers/mongo.manager';\nimport SimpleSchema from 'simpl-schema';\n\nlet schema: any = {\n\t_id: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\t__v: {\n\t\ttype: Number,\n\t\toptional: true\n\t},\n\tupdatedAt: {\n\t\ttype: Date,\n\t\toptional: true\n\t},\n\tcreatedAt: {\n\t\ttype: Date,\n\t\toptional: true\n\t},\n\tmethod: {\n\t\ttype: String\n\t},\n\tparams: {\n\t\ttype: Array, // Declaring params as an array\n\t},\n\t'params.$': {\n\t\ttype: SimpleSchema.oneOf(Object, String, Number, Boolean, Date), // Allowing multiple types\n\t\tblackbox: true // Blackbox for the object type\n\t},\n\tstatus: {\n\t\ttype: String\n\t},\n\tid_user: {\n\t\ttype: String\n\t},\n\tuser: {\n\t\ttype: String\n\t},\n\tid_ws: {\n\t\ttype: String\n\t}\n};\n\nexport let WorkerTaskRequests: MongoManagerCollection<WorkerTaskRequestModel> = null;\n\ninitializeCollection();\n\nfunction initializeCollection() {\n\tif (ResolveIOServer && ResolveIOServer.getMainDB()) {\n\t\tconst model = new MongoManagerModel<WorkerTaskRequestModel>({\n\t\t\tcollectionName: 'worker-task-requests',\n\t\t\tschema: schema,\n\t\t\tuseVersionCollection: false,\n\t\t\tuseReportBuilder: false,\n\t\t\treportBuilderLookupTables: [],\n\t\t\ttimestamps: true,\n\t\t\tcreateLogs: false,\n\t\t\tcheckSchema: false,\n\t\t\tcollectionOptions: null\n\t\t});\n\t\tWorkerTaskRequests = model.collection_main;\n\t\tWorkerTaskRequests.createIndex({createdAt: 1}, {expireAfterSeconds: 60 * 60 * 24 * 90});\n\t\tWorkerTaskRequests.createIndex({status: 1, createdAt: 1});\n\t}\n\telse {\n\t\tsetTimeout(() => {\n\t\t\tinitializeCollection();\n\t\t}, 0);\n\t}\n}"]}
1
+ {"version":3,"sources":["../../src/collections/worker-task-request.collection.ts"],"names":["index_1","require","mongo_manager_1","simpl_schema_1","schema","_id","type","String","optional","__v","Number","updatedAt","Date","createdAt","method","params","Array","params.$","default","oneOf","Object","Boolean","blackbox","status","id_user","user","id_ws","initializeCollection","model","ResolveIOServer","getMainDB","MongoManagerModel","collectionName","useVersionCollection","useReportBuilder","reportBuilderLookupTables","timestamps","createLogs","checkSchema","collectionOptions","exports","WorkerTaskRequests","collection_main","createIndex","expireAfterSeconds","setTimeout"],"mappings":"sGACA,IAAAA,QAAAC,QAAA,UAAA,EACAC,gBAAAD,QAAA,2BAAA,EACAE,eAAAF,QAAA,cAAA,EAEIG,OAAc,CACjBC,IAAK,CACJC,KAAMC,OACNC,SAAU,CAAA,C,EAEXC,IAAK,CACJH,KAAMI,OACNF,SAAU,CAAA,C,EAEXG,UAAW,CACVL,KAAMM,KACNJ,SAAU,CAAA,C,EAEXK,UAAW,CACVP,KAAMM,KACNJ,SAAU,CAAA,C,EAEXM,OAAQ,CACPR,KAAMC,M,EAEPQ,OAAQ,CACPT,KAAMU,K,EAEPC,WAAY,CACXX,KAAMH,eAAAe,QAAaC,MAAMC,OAAQb,OAAQG,OAAQW,QAAST,IAAI,EAC9DU,SAAU,CAAA,C,EAEXC,OAAQ,CACPjB,KAAMC,M,EAEPiB,QAAS,CACRlB,KAAMC,M,EAEPkB,KAAM,CACLnB,KAAMC,M,EAEPmB,MAAO,CACNpB,KAAMC,M,GAQR,SAASoB,uBACR,IACOC,EADH5B,QAAA6B,iBAAmB7B,QAAA6B,gBAAgBC,UAAS,GACzCF,EAAQ,IAAI1B,gBAAA6B,kBAA0C,CAC3DC,eAAgB,uBAChB5B,OAAQA,OACR6B,qBAAsB,CAAA,EACtBC,iBAAkB,CAAA,EAClBC,0BAA2B,GAC3BC,WAAY,CAAA,EACZC,WAAY,CAAA,EACZC,YAAa,CAAA,EACbC,kBAAmB,I,CACnB,EACDC,QAAAC,mBAAqBb,EAAMc,gBAC3BF,QAAAC,mBAAmBE,YAAY,CAAC9B,UAAW,CAAC,EAAG,CAAC+B,mBAAoB,MAAiB,CAAC,EACtFJ,QAAAC,mBAAmBE,YAAY,CAACpB,OAAQ,EAAGV,UAAW,CAAC,CAAC,EACxD2B,QAAAC,mBAAmBE,YAAY,CAACtC,IAAK,EAAGkB,OAAQ,CAAC,CAAC,GAGlDsB,WAAW,WACVlB,qBAAoB,CACrB,EAAG,CAAC,CAEN,CA3BWa,QAAAC,mBAAqE,KAEhFd,qBAAoB","file":"worker-task-request.collection.js","sourcesContent":["import { WorkerTaskRequestModel } from '../models/worker-task-request.model';\nimport { ResolveIOServer } from '../index';\nimport { MongoManagerCollection, MongoManagerModel } from '../managers/mongo.manager';\nimport SimpleSchema from 'simpl-schema';\n\nlet schema: any = {\n\t_id: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\t__v: {\n\t\ttype: Number,\n\t\toptional: true\n\t},\n\tupdatedAt: {\n\t\ttype: Date,\n\t\toptional: true\n\t},\n\tcreatedAt: {\n\t\ttype: Date,\n\t\toptional: true\n\t},\n\tmethod: {\n\t\ttype: String\n\t},\n\tparams: {\n\t\ttype: Array, // Declaring params as an array\n\t},\n\t'params.$': {\n\t\ttype: SimpleSchema.oneOf(Object, String, Number, Boolean, Date), // Allowing multiple types\n\t\tblackbox: true // Blackbox for the object type\n\t},\n\tstatus: {\n\t\ttype: String\n\t},\n\tid_user: {\n\t\ttype: String\n\t},\n\tuser: {\n\t\ttype: String\n\t},\n\tid_ws: {\n\t\ttype: String\n\t}\n};\n\nexport let WorkerTaskRequests: MongoManagerCollection<WorkerTaskRequestModel> = null;\n\ninitializeCollection();\n\nfunction initializeCollection() {\n\tif (ResolveIOServer && ResolveIOServer.getMainDB()) {\n\t\tconst model = new MongoManagerModel<WorkerTaskRequestModel>({\n\t\t\tcollectionName: 'worker-task-requests',\n\t\t\tschema: schema,\n\t\t\tuseVersionCollection: false,\n\t\t\tuseReportBuilder: false,\n\t\t\treportBuilderLookupTables: [],\n\t\t\ttimestamps: true,\n\t\t\tcreateLogs: false,\n\t\t\tcheckSchema: false,\n\t\t\tcollectionOptions: null\n\t\t});\n\t\tWorkerTaskRequests = model.collection_main;\n\t\tWorkerTaskRequests.createIndex({createdAt: 1}, {expireAfterSeconds: 60 * 60 * 24 * 90});\n\t\tWorkerTaskRequests.createIndex({status: 1, createdAt: 1});\n\t\tWorkerTaskRequests.createIndex({_id: 1, status: 1});\n\t}\n\telse {\n\t\tsetTimeout(() => {\n\t\t\tinitializeCollection();\n\t\t}, 0);\n\t}\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@resolveio/server-lib",
3
- "version": "20.3.18",
3
+ "version": "20.3.19",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "package": "./build_package.sh",
package/server-app.d.ts CHANGED
@@ -34,6 +34,7 @@ export default class ResolveIOMainServer {
34
34
  private _debugMsgQueue;
35
35
  private _isWorkersEnabled;
36
36
  private _isWorkerInstance;
37
+ private _workerTasks;
37
38
  private _safeShutdown;
38
39
  constructor(mainServer: any, serverConfig: any, clientRoutes: any, clientDir: any, sesMail: any, standardProgram: any, publicProgram?: boolean);
39
40
  private startServerInstance;
package/server-app.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var __awaiter=this&&this.__awaiter||function(e,n,s,o){return new(s=s||Promise)(function(t,r){function fulfilled(e){try{step(o.next(e))}catch(e){r(e)}}function rejected(e){try{step(o.throw(e))}catch(e){r(e)}}function step(e){var r;e.done?t(e.value):((r=e.value)instanceof s?r:new s(function(e){e(r)})).then(fulfilled,rejected)}step((o=o.apply(e,n||[])).next())})},__generator=this&&this.__generator||function(n,s){var o,i,a,u={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},c={next:verb(0),throw:verb(1),return:verb(2)};return"function"==typeof Symbol&&(c[Symbol.iterator]=function(){return this}),c;function verb(t){return function(e){var r=[t,e];if(o)throw new TypeError("Generator is already executing.");for(;u=c&&r[c=0]?0:u;)try{if(o=1,i&&(a=2&r[0]?i.return:r[0]?i.throw||((a=i.return)&&a.call(i),0):i.next)&&!(a=a.call(i,r[1])).done)return a;switch(i=0,(r=a?[2&r[0],a.value]:r)[0]){case 0:case 1:a=r;break;case 4:return u.label++,{value:r[1],done:!1};case 5:u.label++,i=r[1],r=[0];continue;case 7:r=u.ops.pop(),u.trys.pop();continue;default:if(!(a=0<(a=u.trys).length&&a[a.length-1])&&(6===r[0]||2===r[0])){u=0;continue}if(3===r[0]&&(!a||r[1]>a[0]&&r[1]<a[3]))u.label=r[1];else if(6===r[0]&&u.label<a[1])u.label=a[1],a=r;else{if(!(a&&u.label<a[2])){a[2]&&u.ops.pop(),u.trys.pop();continue}u.label=a[2],u.ops.push(r)}}r=s.call(n,u)}catch(e){r=[6,e],i=0}finally{o=a=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}}},__spreadArray=this&&this.__spreadArray||function(e,r,t){if(t||2===arguments.length)for(var n,s=0,o=r.length;s<o;s++)!n&&s in r||((n=n||Array.prototype.slice.call(r,0,s))[s]=r[s]);return e.concat(n||Array.prototype.slice.call(r))},http_1=(Object.defineProperty(exports,"__esModule",{value:!0}),require("http")),express=require("express"),bodyParser=require("body-parser"),xmlParser=require("express-xml-bodyparser"),WebSocket=require("ws"),jwt=require("jsonwebtoken"),moment=require("moment-timezone"),common_1=require("./util/common"),mongo_manager_1=require("./managers/mongo.manager"),cron_manager_1=require("./managers/cron.manager"),method_manager_1=require("./managers/method.manager"),subscription_manager_1=require("./managers/subscription.manager"),monitor_manager_1=require("./managers/monitor.manager"),method_response_collection_1=require("./collections/method-response.collection"),log_collection_1=require("./collections/log.collection"),log_method_latency_collection_1=require("./collections/log-method-latency.collection"),user_collection_1=require("./collections/user.collection"),home_1=require("./http/home"),auth_1=require("./http/auth"),health_1=require("./http/health"),index_1=require("./index"),mongodb_1=require("mongodb"),worker_task_request_collection_1=require("./collections/worker-task-request.collection"),worker_task_response_collection_1=require("./collections/worker-task-response.collection"),ResolveIOMainServer=function(){function ResolveIOMainServer(e,r,t,n,s,o,i){void 0===i&&(i=!1);var a=this;this._offlineUpdates=[],this._msgQueue=[],this._msgQueueRunning=!1,this.sesMail=!1,this.standardProgram=!1,this.publicProgram=!1,this._rebootFlag=!1,this.LOGGER="ERROR",this._clientRoutes=[],this._lastErrorMsg=null,this._debugMsgRecv=0,this._debugMsgQueue=0,this._isWorkersEnabled=!1,this._isWorkerInstance=!1,this._safeShutdown=!1,this._serverConfig=r,this._clientRoutes=t,this._clientDir=n,this.sesMail=s,this.standardProgram=o,this.publicProgram=i,this._serverStartTime=new Date,this._lastErrorMsg=null,this._monitorManager=new monitor_manager_1.MonitorManager(e,r),this._monitorManagerFunction=new monitor_manager_1.MonitorManagerFunction,this._isWorkersEnabled="true"===process.env.IS_WORKERS_ENABLED,this._isWorkerInstance="true"===process.env.IS_WORKER_INSTANCE,setInterval(function(){a._subscriptionManager&&a._subscriptionManager.getEnableDebug()&&(console.log(new Date,"Server App","Msg Queue Length",a._msgQueue.length),console.log(new Date,"Server App","Msg Recv Hits",a._debugMsgRecv),console.log(new Date,"Server App","Msg Queue Hits",a._debugMsgQueue)),a._debugMsgQueue=0,a._debugMsgRecv=0},6e4),process.on("unhandledRejection",function(n,s){return __awaiter(a,void 0,void 0,function(){var r,t=this;return __generator(this,function(e){switch(e.label){case 0:return n&&"MongoError"===n.name&&48===n.code?[2]:(console.error(new Date,"Unhandled Rejection at Promise",[n,s]),r=moment().diff(this._serverStartTime,"seconds"),n&&("MongoNetworkTimeoutError"===n.name||n instanceof mongodb_1.MongoNetworkTimeoutError)?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - MongoNetworkTimeoutError - Quitting NodeJS - "+this._serverConfig.CLIENT_NAME,JSON.stringify({name:n.name,message:n.message,stack:n.stack},null,2))]):[3,2]:[3,3]);case 1:e.sent(),process.exit(1),e.label=2;case 2:return[3,10];case 3:return n&&"MongoError"===n.name&&"not master"===n.message?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - Quitting NodeJS - "+this._serverConfig.CLIENT_NAME,JSON.stringify([n.name,n.message,n.stack],null,2))]):[3,5]:[3,6];case 4:e.sent(),e.label=5;case 5:return process.exit(1),[3,10];case 6:return n&&"MongoError"===n.name&&"not master and slaveOk=false"===n.message?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - Quitting NodeJS - "+this._serverConfig.CLIENT_NAME,JSON.stringify([n.name,n.message,n.stack],null,2))]):[3,8]:[3,9];case 7:e.sent(),e.label=8;case 8:return process.exit(1),[3,10];case 9:n&&"StatusError"!==n.name&&""!==n.message&&60<r&&!this._lastErrorMsg&&(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - "+this._serverConfig.CLIENT_NAME,JSON.stringify([n.name,n.message,n.stack],null,2))),e.label=10;case 10:return[2]}})})}),process.on("uncaughtException",function(t){return __awaiter(a,void 0,void 0,function(){var r=this;return __generator(this,function(e){switch(e.label){case 0:return(console.error(t,"Uncaught Exception thrown"),60<moment().diff(this._serverStartTime,"seconds")&&!this._lastErrorMsg)?(this._lastErrorMsg=new Date,setTimeout(function(){r._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Exception - "+this._serverConfig.CLIENT_NAME,JSON.stringify([t.name,t.message,t.stack],null,2))]):[3,2];case 1:e.sent(),e.label=2;case 2:return[2]}})})}),process.on("SIGINT",function(){a._rebootFlag=!0,a._serverHTTP.close(),a.safeShutdown()}),process.on("SIGTERM",function(){a._rebootFlag=!0,a._serverHTTP.close(),a.safeShutdown()}),process.on("SIGQUIT",function(){a._rebootFlag=!0,a._serverHTTP.close(),a.safeShutdown()}),"DEBUG"===this.LOGGER&&console.log("Starting ResolveIO Server"),this._isWorkersEnabled?this._isWorkerInstance?(console.log("Running as a Worker instance"),this._methodManager=new method_manager_1.MethodManager(this,this._serverConfig,this._clientDir,this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._cronManager=new cron_manager_1.CronManager(this),this.startWorkerInstance()):(console.log("Running as a Server instance"),this.startServerInstance(r),this._methodManager=new method_manager_1.MethodManager(this,this._serverConfig,this._clientDir,this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._subscriptionManager=new subscription_manager_1.SubscriptionManager(this,this._serverWSS,this._serverConfig,this._monitorManagerFunction),this.listen()):(console.log("Running with Workers Disabled"),this.startServerInstance(r),this._methodManager=new method_manager_1.MethodManager(this,this._serverConfig,this._clientDir,this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._subscriptionManager=new subscription_manager_1.SubscriptionManager(this,this._serverWSS,this._serverConfig,this._monitorManagerFunction),this._cronManager=new cron_manager_1.CronManager(this),this.listen())}return ResolveIOMainServer.prototype.startServerInstance=function(e){this._app=express(),this._app.use(bodyParser.json({limit:"50mb",reviver:common_1.dateReviver})),this._app.use(bodyParser.urlencoded({limit:"50mb",extended:!0,parameterLimit:1e6})),this._app.use(xmlParser()),this._portHTTP=process.env.PORT_HTTP||e.PORT_HTTP||8080,this._portWSS=process.env.PORT_WSS||e.PORT_WSS||8081,"DEBUG"===this.LOGGER&&console.log("Setup ports"),this.createServer(),"DEBUG"===this.LOGGER&&console.log("Create server"),this._app.use(function(e,r,t){r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Allow-Methods","GET, POST"),r.setHeader("Access-Control-Allow-Headers","X-Requested-With,content-type"),r.setHeader("Access-Control-Allow-Credentials","false"),t()}),"DEBUG"===this.LOGGER&&console.log("Setup cors"),(0,auth_1.setupAuthRoutes)(this,this._app,e),(0,health_1.setupHealthRoutes)(this._app,e),"ResolveIO"!==e.CLIENT_NAME&&!this.standardProgram||(0,home_1.setupHomeRoutes)(this,this._app,e),"DEBUG"===this.LOGGER&&console.log("Setup express routes")},ResolveIOMainServer.prototype.startWorkerInstance=function(){return __awaiter(this,void 0,void 0,function(){var r,t,n,s,o=this;return __generator(this,function(e){switch(e.label){case 0:return console.log("Worker instance started, watching worker-task-reqs..."),(r=worker_task_request_collection_1.WorkerTaskRequests.watchCollection([{$match:{"fullDocument.status":"pending"}}],{fullDocument:"updateLookup"})).on("change",function(t){return __awaiter(o,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return"insert"!==t.operationType?[3,2]:(r=t.fullDocument)?[4,this.processTask(r)]:[3,2];case 1:e.sent(),e.label=2;case 2:return[2]}})})}),r.on("error",function(e){console.error("Error in change stream worker task requests:",e),r.close(),setTimeout(function(){return o.startWorkerInstance()},5e3)}),r.on("close",function(){console.log("Change stream worker task requests closed. Restarting..."),setTimeout(function(){return o.startWorkerInstance()},5e3)}),[4,worker_task_request_collection_1.WorkerTaskRequests.find({status:"pending"},{sort:{createdAt:1}})];case 1:n=e.sent(),t=0,n=n,e.label=2;case 2:return t<n.length?(s=n[t],console.log("Processing existing pending task:",s._id),[4,this.processTask(s)]):[3,5];case 3:e.sent(),e.label=4;case 4:return t++,[3,2];case 5:return[2]}})})},ResolveIOMainServer.prototype.processTask=function(n){return __awaiter(this,void 0,void 0,function(){var r,t;return __generator(this,function(e){switch(e.label){case 0:return[4,worker_task_request_collection_1.WorkerTaskRequests.findOneAndUpdate({_id:n._id,status:"pending"},{$set:{status:"processing"}})];case 1:if(!e.sent())return[3,6];e.label=2;case 2:return e.trys.push([2,4,,5]),[4,(t=this._methodManager.callMethodInternal).call.apply(t,__spreadArray([Object.assign({},this._methodManager,{id_user:n.id_user,user:n.user,id_ws:n.id_ws}),n.method],n.params,!1))];case 3:return t=e.sent(),worker_task_response_collection_1.WorkerTaskResponses.create({id_request:n._id,has_error:!1,data:t,id_user:n.id_user,user:n.user,id_ws:n.id_ws}),[3,5];case 4:return r=e.sent(),console.error("Worker failed to process task:",n._id,r),worker_task_response_collection_1.WorkerTaskResponses.create({id_request:n._id,has_error:!0,data:r.message,id_user:n.id_user,user:n.user,id_ws:n.id_ws}),[3,5];case 5:worker_task_request_collection_1.WorkerTaskRequests.updateOne({_id:n._id},{$set:{status:"complete"}}),e.label=6;case 6:return[2]}})})},ResolveIOMainServer.prototype.safeShutdown=function(){var e=this;this._safeShutdown||console.log(new Date,"Safe Shutdown Command Received"),this._monitorManagerFunction.getActiveMonitorFunctions().length||this._msgQueue.length||this._msgQueueRunning||this._offlineUpdates.length?(this._safeShutdown||(this._safeShutdown=!0,setTimeout(function(){e._safeShutdown=!1},1e3),console.log(new Date,"Safe Exit In Progress",this._monitorManagerFunction.getActiveMonitorFunctions().length,this._msgQueue.length,this._msgQueueRunning,this._offlineUpdates.length)),setImmediate(function(){e.safeShutdown()})):index_1.ResolveIOServer.getMongoConnection().close(!1).then(function(){console.log(new Date,"Safe Exit Complete, Process Exit"),process.exit(0)},function(){process.exit(1)})},ResolveIOMainServer.prototype.getIsWorkersEnabled=function(){return this._isWorkersEnabled},ResolveIOMainServer.prototype.getIsWorkerInstance=function(){return this._isWorkerInstance},ResolveIOMainServer.prototype.getWS=function(r){return Array.from(this._serverWSS.clients).filter(function(e){return e.id_socket===r})[0]},ResolveIOMainServer.prototype.getWSList=function(){var r=[];return this._serverWSS.clients.forEach(function(e){r.push(e.id_socket)}),r},ResolveIOMainServer.prototype.getWSUserList=function(){var r=[];return this._serverWSS.clients.forEach(function(e){r.push(e.id_user)}),r},ResolveIOMainServer.prototype.getHTTPServer=function(){return this._serverHTTP},ResolveIOMainServer.prototype.getCronManager=function(){return this._cronManager},ResolveIOMainServer.prototype.getMethodManager=function(){return this._methodManager},ResolveIOMainServer.prototype.getSubscriptionManager=function(){return this._subscriptionManager},ResolveIOMainServer.prototype.getMonitorManager=function(){return this._monitorManager},ResolveIOMainServer.prototype.getRebootFlag=function(){return this._rebootFlag},ResolveIOMainServer.prototype.createServer=function(){var e=this;this._serverHTTP=(0,http_1.createServer)(this._app),this._serverHTTP.keepAliveTimeout=65e3,this._serverHTTP.headersTimeout=66e3,this._serverWSS=new WebSocket.Server({port:this._portWSS,verifyClient:this.publicProgram?null:function(o,i){return __awaiter(e,void 0,void 0,function(){var r,s=this;return __generator(this,function(e){return this._rebootFlag?i(!1,409,"Unable To Process"):("DEBUG"===this.LOGGER&&console.log("Verify Client",o,i),r=o.req.headers["sec-websocket-protocol"].split(/,/),(o.origin===this._serverConfig.ROOT_URL||o.origin===this._serverConfig.SEC_ROOT_URL||o.origin===this._serverConfig.RESOLVEIO_URL||o.origin===this._serverConfig.RESOLVEIO_SECONDARY_URL)&&(r=r[0])?jwt.verify(r,this._serverConfig.JWT_SECRET,function(t,n){return __awaiter(s,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return t?(i(!1,401,"Unauthorized"),[3,5]):[3,1];case 1:o.req.id_user=n.id_user,e.label=2;case 2:return e.trys.push([2,4,,5]),[4,user_collection_1.Users.findById(n.id_user)];case 3:return(r=e.sent())?(o.req.user=r.fullname,o.req.user_readonly=r.readonly||!1,o.req.doc_user=r,i(!0)):i(!1),[3,5];case 4:return e.sent(),i(!1),[3,5];case 5:return[2]}})})}):i(!1,401,"Unauthorized")),[2]})})}})},ResolveIOMainServer.prototype.listen=function(){var u=this;this._serverHTTP.listen(this._portHTTP,function(){console.log("Running server on port %s",u._portHTTP)}),this._serverWSS.on("listening",function(){console.log("Running server on port %s",u._portWSS)}),this._serverWSS.on("connection",function(f,e){u.publicProgram||(f.id_user=e.id_user,f.user=e.user,f.user_readonly=e.user_readonly,f.doc_user=e.doc_user,"Admin"!==f.user&&"ResolveIO"!==u._serverConfig.CLIENT_NAME&&u.getMethodManager().callMethodInternal.call(u.getMethodManager(),"supportCreateBillingUser",{id_user:f.id_user,user:f.user,date:new Date,client:index_1.ResolveIOServer.getClientName()})),f.id_socket=(0,mongo_manager_1.objectIdHexString)(),f.retryCnt=0,u._subscriptionManager.createLoggedInUser(f.id_socket).then(function(){setTimeout(function(){f.pingTime=new Date,f.ping(function(){})},5e3)}),"DEBUG"===u.LOGGER&&console.log("Connection from: "+e.user),f.isAlive=!0,f.on("pong",function(){f.isAlive=!0,f.pongTime=new Date,f.latency=moment.duration(moment(f.pongTime).diff(f.pingTime)).asMilliseconds(),u._subscriptionManager.loggedInLatency(f)}).on("message",function(p){return __awaiter(u,void 0,void 0,function(){var r,t,n,s,o,i,a,u,c,l,_,g,h,d=this;return __generator(this,function(e){switch(e.label){case 0:"DEBUG"===this.LOGGER&&console.log("Message from: "+f.user,p),this._debugMsgRecv+=1,u=!1,r=[];try{r=JSON.parse(p,common_1.dateReviver)}catch(e){console.log("Error - JSON.parse",p),this._methodManager.sendEmail("dev@resolveio.com","SERVER - JSON Parse Error - "+this._serverConfig.CLIENT_NAME,JSON.stringify([p,e])),u=!0}if(!u){if("ping"===r[0])return f&&f.readyState===f.OPEN&&f.send("pong",function(e){e&&(d._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Pong"),d.unsubscribeWS(f))}),[2];if(t=r[0],!this.publicProgram&&this._clientRoutes.some(function(e){return t.includes(e)})&&!f.doc_user.roles.groups.some(function(e){return e.views.some(function(e){return t.includes(e)||e.includes(t)})})&&!f.doc_user.roles.super_admin)return[2];if(u=r[1],n=r[2],"subscription"!==(s=r[3]))return[3,1];o=r[4],l=r[5],"sub"===o?this._subscriptionManager.subscribe(t,u,f,n,l,r.slice(6)):this._subscriptionManager.unsubscribe(t,u,f,n,l,r.slice(6))}return[3,11];case 1:if(this.publicProgram||"offline"!==s)return[3,10];o={messageId:n,hasError:!1,data:"ACK"},f&&f.readyState===f.OPEN&&f.send(JSON.stringify(o),function(e){e&&(d._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Offline Ack Main"),d.unsubscribeWS(f))}),this._offlineUpdates.push(f),i=r[4],a=0,e.label=2;case 2:if(!(a<i.length))return[3,9];if(u=i[a],c=u.data,l={messageId:u.data[2],hasError:!1,data:"ACK"},f&&f.readyState===f.OPEN&&f.send(JSON.stringify(l),function(e){e&&(d._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Offline Ack Each"),d.unsubscribeWS(f))}),c.shift(),c.shift(),c.shift(),c.shift(),_=c.shift(),h=(0,mongo_manager_1.objectIdHexString)(),log_method_latency_collection_1.LogMethodLatencies.create({_id:h,__v:0,date_start:new Date,date_end:null,latency_ms:0,method:_}),"reportBuilderGetResults"!==_&&"reportBuilderGetDistinctValue"!==_&&"reportBuilderBuildTree"!==_&&"generatePDF"!==_&&"getWOOfflineData"!==_&&"countQuery"!==_&&"countWithQuery"!==_&&"countCollectionWithQuery"!==_&&"find"!==_&&"findOne"!==_&&"findWithOptions"!==_&&"getDrivers"!==_&&"processAirdropDistribution"!==_&&log_collection_1.Logs.insertOne({_id:(0,mongo_manager_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(c))<2e5?JSON.stringify(c,null,2):"Too Big",method:_,id_user:f.id_user||"",user:f.user||"",messageId:n,route:t}),!this._methodManager._methods[_])return[3,7];e.label=3;case 3:return e.trys.push([3,5,,6]),[4,(h=this._methodManager.callMethodInternal).call.apply(h,__spreadArray([Object.assign({},this._methodManager,{id_user:f.id_user,user:f.user,id_ws:f.id_socket}),_],c,!1))];case 4:return e.sent(),[3,6];case 5:return g=e.sent(),console.log(new Date,"Offline Error",JSON.stringify(g,null,2)),[3,6];case 6:return"updateDocumentOffline"!==_&&"updateDocumentPropsOffline"!==_||index_1.ResolveIOServer.getMongoManager().invalidateQueryCache(c[0]),[3,8];case 7:console.log("Offline - Could not find method: "+_),e.label=8;case 8:return a++,[3,2];case 9:return this._offlineUpdates.splice(this._offlineUpdates.map(function(e){return e.id_socket}).indexOf(f.id_socket),1),[3,11];case 10:this._msgQueue.splice(0,0,{ws:f,data:r}),e.label=11;case 11:return[2]}})})}).on("end",function(){u.unsubscribeWS(f),u._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","WS End")}).on("close",function(){u.unsubscribeWS(f),u._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","WS Close")}).on("error",function(e){u.unsubscribeWS(f),u._subscriptionManager.getEnableDebug()&&console.log(new Date,f.user,f.id_socket,"WS Error")})}),setInterval(function(){u._serverWSS.clients.forEach(function(e){e.pingTime&&2e4<=Date.now()-e.pingTime.getTime()&&(!1===e.isAlive?(e.retryCnt++,3<=e.retryCnt?u.unsubscribeWS(e):(e.pingTime=new Date,e.ping(function(){}))):(e.retryCnt=0,e.isAlive=!1,e.pingTime=new Date,e.ping(function(){})))})},2e4),setInterval(function(){if(!u._msgQueueRunning&&u._msgQueue.length){u._msgQueueRunning=!0,u._debugMsgQueue+=1;var e=u._msgQueue.pop(),r=e.data,t=e.ws,e=r.shift(),n=r.shift(),s=r.shift(),o=r.shift();if("method"===o){var i=r.shift();if(t.user_readonly)return;var a=(0,mongo_manager_1.objectIdHexString)(),e=(log_method_latency_collection_1.LogMethodLatencies.create({_id:a,__v:0,date_start:new Date,date_end:null,latency_ms:0,method:i}),"reportBuilderGetResults"!==i&&"reportBuilderGetDistinctValue"!==i&&"reportBuilderBuildTree"!==i&&"generatePDF"!==i&&"getWOOfflineData"!==i&&"countQuery"!==i&&"countWithQuery"!==i&&"countCollectionWithQuery"!==i&&"find"!==i&&"findOne"!==i&&"findWithOptions"!==i&&"getDrivers"!==i&&"processAirdropDistribution"!==i&&log_collection_1.Logs.insertOne({_id:(0,mongo_manager_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(r))<2e5?JSON.stringify(r,null,2):"Too Big",method:i,id_user:t.id_user||"",user:t.user||"",messageId:s,route:e}),{messageId:s,hasError:!1,data:"ACK"});t&&t.readyState===t.OPEN&&t.send(JSON.stringify(e),function(e){e&&u.unsubscribeWS(t)}),u._methodManager._methods[i]?(e=u._methodManager).callMethod.apply(e,__spreadArray([a,t,n,s,i],r,!1)):console.log("Could not find method: "+i)}else"methodResponse"===o&&(i=r.shift(),method_response_collection_1.MethodResponses.findOne({$and:[{id_user:t.id_user},{message_id:s},{method:i},{date:n}]}).then(function(e){e&&t&&t.readyState===t.OPEN&&t.send(JSON.stringify(e.response),function(e){e&&u.unsubscribeWS(t)})},function(e){}));u._msgQueueRunning=!1}},1)},ResolveIOMainServer.prototype.unsubscribeWS=function(e){this._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Unsub WS",e.user,e.id_socket),this._subscriptionManager.unsubscribeAll(e),e.removeAllListeners()},ResolveIOMainServer.prototype.getApp=function(){return this._app},ResolveIOMainServer.prototype.getServerConfig=function(){return this._serverConfig},ResolveIOMainServer}();exports.default=ResolveIOMainServer;
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(e,n,s,o){return new(s=s||Promise)(function(t,r){function fulfilled(e){try{step(o.next(e))}catch(e){r(e)}}function rejected(e){try{step(o.throw(e))}catch(e){r(e)}}function step(e){var r;e.done?t(e.value):((r=e.value)instanceof s?r:new s(function(e){e(r)})).then(fulfilled,rejected)}step((o=o.apply(e,n||[])).next())})},__generator=this&&this.__generator||function(n,s){var o,i,a,u={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},c={next:verb(0),throw:verb(1),return:verb(2)};return"function"==typeof Symbol&&(c[Symbol.iterator]=function(){return this}),c;function verb(t){return function(e){var r=[t,e];if(o)throw new TypeError("Generator is already executing.");for(;u=c&&r[c=0]?0:u;)try{if(o=1,i&&(a=2&r[0]?i.return:r[0]?i.throw||((a=i.return)&&a.call(i),0):i.next)&&!(a=a.call(i,r[1])).done)return a;switch(i=0,(r=a?[2&r[0],a.value]:r)[0]){case 0:case 1:a=r;break;case 4:return u.label++,{value:r[1],done:!1};case 5:u.label++,i=r[1],r=[0];continue;case 7:r=u.ops.pop(),u.trys.pop();continue;default:if(!(a=0<(a=u.trys).length&&a[a.length-1])&&(6===r[0]||2===r[0])){u=0;continue}if(3===r[0]&&(!a||r[1]>a[0]&&r[1]<a[3]))u.label=r[1];else if(6===r[0]&&u.label<a[1])u.label=a[1],a=r;else{if(!(a&&u.label<a[2])){a[2]&&u.ops.pop(),u.trys.pop();continue}u.label=a[2],u.ops.push(r)}}r=s.call(n,u)}catch(e){r=[6,e],i=0}finally{o=a=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}}},__spreadArray=this&&this.__spreadArray||function(e,r,t){if(t||2===arguments.length)for(var n,s=0,o=r.length;s<o;s++)!n&&s in r||((n=n||Array.prototype.slice.call(r,0,s))[s]=r[s]);return e.concat(n||Array.prototype.slice.call(r))},http_1=(Object.defineProperty(exports,"__esModule",{value:!0}),require("http")),express=require("express"),bodyParser=require("body-parser"),xmlParser=require("express-xml-bodyparser"),WebSocket=require("ws"),jwt=require("jsonwebtoken"),moment=require("moment-timezone"),common_1=require("./util/common"),mongo_manager_1=require("./managers/mongo.manager"),cron_manager_1=require("./managers/cron.manager"),method_manager_1=require("./managers/method.manager"),subscription_manager_1=require("./managers/subscription.manager"),monitor_manager_1=require("./managers/monitor.manager"),method_response_collection_1=require("./collections/method-response.collection"),log_collection_1=require("./collections/log.collection"),log_method_latency_collection_1=require("./collections/log-method-latency.collection"),user_collection_1=require("./collections/user.collection"),home_1=require("./http/home"),auth_1=require("./http/auth"),health_1=require("./http/health"),index_1=require("./index"),mongodb_1=require("mongodb"),worker_task_request_collection_1=require("./collections/worker-task-request.collection"),worker_task_response_collection_1=require("./collections/worker-task-response.collection"),ResolveIOMainServer=function(){function ResolveIOMainServer(e,r,t,n,s,o,i){void 0===i&&(i=!1);var a=this;this._offlineUpdates=[],this._msgQueue=[],this._msgQueueRunning=!1,this.sesMail=!1,this.standardProgram=!1,this.publicProgram=!1,this._rebootFlag=!1,this.LOGGER="ERROR",this._clientRoutes=[],this._lastErrorMsg=null,this._debugMsgRecv=0,this._debugMsgQueue=0,this._isWorkersEnabled=!1,this._isWorkerInstance=!1,this._workerTasks=[],this._safeShutdown=!1,this._serverConfig=r,this._clientRoutes=t,this._clientDir=n,this.sesMail=s,this.standardProgram=o,this.publicProgram=i,this._serverStartTime=new Date,this._lastErrorMsg=null,this._monitorManager=new monitor_manager_1.MonitorManager(e,r),this._monitorManagerFunction=new monitor_manager_1.MonitorManagerFunction,this._isWorkersEnabled="true"===process.env.IS_WORKERS_ENABLED,this._isWorkerInstance="true"===process.env.IS_WORKER_INSTANCE,setInterval(function(){a._subscriptionManager&&a._subscriptionManager.getEnableDebug()&&(console.log(new Date,"Server App","Msg Queue Length",a._msgQueue.length),console.log(new Date,"Server App","Msg Recv Hits",a._debugMsgRecv),console.log(new Date,"Server App","Msg Queue Hits",a._debugMsgQueue)),a._debugMsgQueue=0,a._debugMsgRecv=0},6e4),process.on("unhandledRejection",function(n,s){return __awaiter(a,void 0,void 0,function(){var r,t=this;return __generator(this,function(e){switch(e.label){case 0:return n&&"MongoError"===n.name&&48===n.code?[2]:(console.error(new Date,"Unhandled Rejection at Promise",[n,s]),r=moment().diff(this._serverStartTime,"seconds"),n&&("MongoNetworkTimeoutError"===n.name||n instanceof mongodb_1.MongoNetworkTimeoutError)?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - MongoNetworkTimeoutError - Quitting NodeJS - "+this._serverConfig.CLIENT_NAME,JSON.stringify({name:n.name,message:n.message,stack:n.stack},null,2))]):[3,2]:[3,3]);case 1:e.sent(),process.exit(1),e.label=2;case 2:return[3,10];case 3:return n&&"MongoError"===n.name&&"not master"===n.message?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - Quitting NodeJS - "+this._serverConfig.CLIENT_NAME,JSON.stringify([n.name,n.message,n.stack],null,2))]):[3,5]:[3,6];case 4:e.sent(),e.label=5;case 5:return process.exit(1),[3,10];case 6:return n&&"MongoError"===n.name&&"not master and slaveOk=false"===n.message?60<r&&!this._lastErrorMsg?(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - Quitting NodeJS - "+this._serverConfig.CLIENT_NAME,JSON.stringify([n.name,n.message,n.stack],null,2))]):[3,8]:[3,9];case 7:e.sent(),e.label=8;case 8:return process.exit(1),[3,10];case 9:n&&"StatusError"!==n.name&&""!==n.message&&60<r&&!this._lastErrorMsg&&(this._lastErrorMsg=new Date,setTimeout(function(){t._lastErrorMsg=null},6e4),this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Rejection - "+this._serverConfig.CLIENT_NAME,JSON.stringify([n.name,n.message,n.stack],null,2))),e.label=10;case 10:return[2]}})})}),process.on("uncaughtException",function(t){return __awaiter(a,void 0,void 0,function(){var r=this;return __generator(this,function(e){switch(e.label){case 0:return(console.error(t,"Uncaught Exception thrown"),60<moment().diff(this._serverStartTime,"seconds")&&!this._lastErrorMsg)?(this._lastErrorMsg=new Date,setTimeout(function(){r._lastErrorMsg=null},6e4),[4,this._methodManager.sendEmail("dev@resolveio.com","SERVER - Unhandled Exception - "+this._serverConfig.CLIENT_NAME,JSON.stringify([t.name,t.message,t.stack],null,2))]):[3,2];case 1:e.sent(),e.label=2;case 2:return[2]}})})}),process.on("SIGINT",function(){a._rebootFlag=!0,a._serverHTTP.close(),a.safeShutdown()}),process.on("SIGTERM",function(){a._rebootFlag=!0,a._serverHTTP.close(),a.safeShutdown()}),process.on("SIGQUIT",function(){a._rebootFlag=!0,a._serverHTTP.close(),a.safeShutdown()}),"DEBUG"===this.LOGGER&&console.log("Starting ResolveIO Server"),this._isWorkersEnabled?this._isWorkerInstance?(console.log("Running as a Worker instance"),this._methodManager=new method_manager_1.MethodManager(this,this._serverConfig,this._clientDir,this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._cronManager=new cron_manager_1.CronManager(this),this.startWorkerInstance()):(console.log("Running as a Server instance"),this.startServerInstance(r),this._methodManager=new method_manager_1.MethodManager(this,this._serverConfig,this._clientDir,this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._subscriptionManager=new subscription_manager_1.SubscriptionManager(this,this._serverWSS,this._serverConfig,this._monitorManagerFunction),this.listen()):(console.log("Running with Workers Disabled"),this.startServerInstance(r),this._methodManager=new method_manager_1.MethodManager(this,this._serverConfig,this._clientDir,this._monitorManagerFunction,this._isWorkersEnabled,this._isWorkerInstance),this._subscriptionManager=new subscription_manager_1.SubscriptionManager(this,this._serverWSS,this._serverConfig,this._monitorManagerFunction),this._cronManager=new cron_manager_1.CronManager(this),this.listen())}return ResolveIOMainServer.prototype.startServerInstance=function(e){this._app=express(),this._app.use(bodyParser.json({limit:"50mb",reviver:common_1.dateReviver})),this._app.use(bodyParser.urlencoded({limit:"50mb",extended:!0,parameterLimit:1e6})),this._app.use(xmlParser()),this._portHTTP=process.env.PORT_HTTP||e.PORT_HTTP||8080,this._portWSS=process.env.PORT_WSS||e.PORT_WSS||8081,"DEBUG"===this.LOGGER&&console.log("Setup ports"),this.createServer(),"DEBUG"===this.LOGGER&&console.log("Create server"),this._app.use(function(e,r,t){r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Allow-Methods","GET, POST"),r.setHeader("Access-Control-Allow-Headers","X-Requested-With,content-type"),r.setHeader("Access-Control-Allow-Credentials","false"),t()}),"DEBUG"===this.LOGGER&&console.log("Setup cors"),(0,auth_1.setupAuthRoutes)(this,this._app,e),(0,health_1.setupHealthRoutes)(this._app,e),"ResolveIO"!==e.CLIENT_NAME&&!this.standardProgram||(0,home_1.setupHomeRoutes)(this,this._app,e),"DEBUG"===this.LOGGER&&console.log("Setup express routes")},ResolveIOMainServer.prototype.startWorkerInstance=function(){return __awaiter(this,void 0,void 0,function(){var r,t,n,s,o=this;return __generator(this,function(e){switch(e.label){case 0:return console.log("Worker instance started, watching worker-task-reqs..."),(r=worker_task_request_collection_1.WorkerTaskRequests.watchCollection([{$match:{"fullDocument.status":"pending"}}],{fullDocument:"updateLookup"})).on("change",function(n){return __awaiter(o,void 0,void 0,function(){var r,t=this;return __generator(this,function(e){return"insert"===n.operationType&&(r=n.fullDocument)&&(this._workerTasks.length?setTimeout(function(){t.processTask(r)},50*this._workerTasks.length):this.processTask(r)),[2]})})}),r.on("error",function(e){console.error("Error in change stream worker task requests:",e),r.close(),setTimeout(function(){return o.startWorkerInstance()},5e3)}),r.on("close",function(){console.log("Change stream worker task requests closed. Restarting..."),setTimeout(function(){return o.startWorkerInstance()},5e3)}),[4,worker_task_request_collection_1.WorkerTaskRequests.find({status:"pending"},{sort:{createdAt:1}})];case 1:n=e.sent(),t=0,n=n,e.label=2;case 2:return t<n.length?(s=n[t],console.log("Processing existing pending task:",s._id),[4,this.processTask(s)]):[3,5];case 3:e.sent(),e.label=4;case 4:return t++,[3,2];case 5:return[2]}})})},ResolveIOMainServer.prototype.processTask=function(s){return __awaiter(this,void 0,void 0,function(){var r=this;return __generator(this,function(e){return worker_task_request_collection_1.WorkerTaskRequests.updateOne({_id:s._id,status:"pending"},{$set:{status:"processing"}}).then(function(n){return __awaiter(r,void 0,void 0,function(){var r,t;return __generator(this,function(e){switch(e.label){case 0:if(!n)return[3,5];this._workerTasks.push(s._id),e.label=1;case 1:return e.trys.push([1,3,,4]),[4,(t=this._methodManager.callMethodInternal).call.apply(t,__spreadArray([Object.assign({},this._methodManager,{id_user:s.id_user,user:s.user,id_ws:s.id_ws}),s.method],s.params,!1))];case 2:return t=e.sent(),this._workerTasks.includes(s._id)&&this._workerTasks.splice(this._workerTasks.indexOf(s._id),1),worker_task_response_collection_1.WorkerTaskResponses.create({id_request:s._id,has_error:!1,data:t,id_user:s.id_user,user:s.user,id_ws:s.id_ws}),[3,4];case 3:return r=e.sent(),console.error("Worker failed to process task:",s._id,r),this._workerTasks.includes(s._id)&&this._workerTasks.splice(this._workerTasks.indexOf(s._id),1),worker_task_response_collection_1.WorkerTaskResponses.create({id_request:s._id,has_error:!0,data:r.message,id_user:s.id_user,user:s.user,id_ws:s.id_ws}),[3,4];case 4:worker_task_request_collection_1.WorkerTaskRequests.updateOne({_id:s._id},{$set:{status:"complete"}}),e.label=5;case 5:return[2]}})})},function(){}),[2]})})},ResolveIOMainServer.prototype.safeShutdown=function(){var e=this;this._safeShutdown||console.log(new Date,"Safe Shutdown Command Received"),this._monitorManagerFunction.getActiveMonitorFunctions().length||this._msgQueue.length||this._msgQueueRunning||this._offlineUpdates.length?(this._safeShutdown||(this._safeShutdown=!0,setTimeout(function(){e._safeShutdown=!1},1e3),console.log(new Date,"Safe Exit In Progress",this._monitorManagerFunction.getActiveMonitorFunctions().length,this._msgQueue.length,this._msgQueueRunning,this._offlineUpdates.length)),setImmediate(function(){e.safeShutdown()})):index_1.ResolveIOServer.getMongoConnection().close(!1).then(function(){console.log(new Date,"Safe Exit Complete, Process Exit"),process.exit(0)},function(){process.exit(1)})},ResolveIOMainServer.prototype.getIsWorkersEnabled=function(){return this._isWorkersEnabled},ResolveIOMainServer.prototype.getIsWorkerInstance=function(){return this._isWorkerInstance},ResolveIOMainServer.prototype.getWS=function(r){return Array.from(this._serverWSS.clients).filter(function(e){return e.id_socket===r})[0]},ResolveIOMainServer.prototype.getWSList=function(){var r=[];return this._serverWSS.clients.forEach(function(e){r.push(e.id_socket)}),r},ResolveIOMainServer.prototype.getWSUserList=function(){var r=[];return this._serverWSS.clients.forEach(function(e){r.push(e.id_user)}),r},ResolveIOMainServer.prototype.getHTTPServer=function(){return this._serverHTTP},ResolveIOMainServer.prototype.getCronManager=function(){return this._cronManager},ResolveIOMainServer.prototype.getMethodManager=function(){return this._methodManager},ResolveIOMainServer.prototype.getSubscriptionManager=function(){return this._subscriptionManager},ResolveIOMainServer.prototype.getMonitorManager=function(){return this._monitorManager},ResolveIOMainServer.prototype.getRebootFlag=function(){return this._rebootFlag},ResolveIOMainServer.prototype.createServer=function(){var e=this;this._serverHTTP=(0,http_1.createServer)(this._app),this._serverHTTP.keepAliveTimeout=65e3,this._serverHTTP.headersTimeout=66e3,this._serverWSS=new WebSocket.Server({port:this._portWSS,verifyClient:this.publicProgram?null:function(o,i){return __awaiter(e,void 0,void 0,function(){var r,s=this;return __generator(this,function(e){return this._rebootFlag?i(!1,409,"Unable To Process"):("DEBUG"===this.LOGGER&&console.log("Verify Client",o,i),r=o.req.headers["sec-websocket-protocol"].split(/,/),(o.origin===this._serverConfig.ROOT_URL||o.origin===this._serverConfig.SEC_ROOT_URL||o.origin===this._serverConfig.RESOLVEIO_URL||o.origin===this._serverConfig.RESOLVEIO_SECONDARY_URL)&&(r=r[0])?jwt.verify(r,this._serverConfig.JWT_SECRET,function(t,n){return __awaiter(s,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return t?(i(!1,401,"Unauthorized"),[3,5]):[3,1];case 1:o.req.id_user=n.id_user,e.label=2;case 2:return e.trys.push([2,4,,5]),[4,user_collection_1.Users.findById(n.id_user)];case 3:return(r=e.sent())?(o.req.user=r.fullname,o.req.user_readonly=r.readonly||!1,o.req.doc_user=r,i(!0)):i(!1),[3,5];case 4:return e.sent(),i(!1),[3,5];case 5:return[2]}})})}):i(!1,401,"Unauthorized")),[2]})})}})},ResolveIOMainServer.prototype.listen=function(){var u=this;this._serverHTTP.listen(this._portHTTP,function(){console.log("Running server on port %s",u._portHTTP)}),this._serverWSS.on("listening",function(){console.log("Running server on port %s",u._portWSS)}),this._serverWSS.on("connection",function(f,e){u.publicProgram||(f.id_user=e.id_user,f.user=e.user,f.user_readonly=e.user_readonly,f.doc_user=e.doc_user,"Admin"!==f.user&&"ResolveIO"!==u._serverConfig.CLIENT_NAME&&u.getMethodManager().callMethodInternal.call(u.getMethodManager(),"supportCreateBillingUser",{id_user:f.id_user,user:f.user,date:new Date,client:index_1.ResolveIOServer.getClientName()})),f.id_socket=(0,mongo_manager_1.objectIdHexString)(),f.retryCnt=0,u._subscriptionManager.createLoggedInUser(f.id_socket).then(function(){setTimeout(function(){f.pingTime=new Date,f.ping(function(){})},5e3)}),"DEBUG"===u.LOGGER&&console.log("Connection from: "+e.user),f.isAlive=!0,f.on("pong",function(){f.isAlive=!0,f.pongTime=new Date,f.latency=moment.duration(moment(f.pongTime).diff(f.pingTime)).asMilliseconds(),u._subscriptionManager.loggedInLatency(f)}).on("message",function(p){return __awaiter(u,void 0,void 0,function(){var r,t,n,s,o,i,a,u,c,l,_,g,h,d=this;return __generator(this,function(e){switch(e.label){case 0:"DEBUG"===this.LOGGER&&console.log("Message from: "+f.user,p),this._debugMsgRecv+=1,u=!1,r=[];try{r=JSON.parse(p,common_1.dateReviver)}catch(e){console.log("Error - JSON.parse",p),this._methodManager.sendEmail("dev@resolveio.com","SERVER - JSON Parse Error - "+this._serverConfig.CLIENT_NAME,JSON.stringify([p,e])),u=!0}if(!u){if("ping"===r[0])return f&&f.readyState===f.OPEN&&f.send("pong",function(e){e&&(d._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Pong"),d.unsubscribeWS(f))}),[2];if(t=r[0],!this.publicProgram&&this._clientRoutes.some(function(e){return t.includes(e)})&&!f.doc_user.roles.groups.some(function(e){return e.views.some(function(e){return t.includes(e)||e.includes(t)})})&&!f.doc_user.roles.super_admin)return[2];if(u=r[1],n=r[2],"subscription"!==(s=r[3]))return[3,1];o=r[4],l=r[5],"sub"===o?this._subscriptionManager.subscribe(t,u,f,n,l,r.slice(6)):this._subscriptionManager.unsubscribe(t,u,f,n,l,r.slice(6))}return[3,11];case 1:if(this.publicProgram||"offline"!==s)return[3,10];o={messageId:n,hasError:!1,data:"ACK"},f&&f.readyState===f.OPEN&&f.send(JSON.stringify(o),function(e){e&&(d._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Offline Ack Main"),d.unsubscribeWS(f))}),this._offlineUpdates.push(f),i=r[4],a=0,e.label=2;case 2:if(!(a<i.length))return[3,9];if(u=i[a],c=u.data,l={messageId:u.data[2],hasError:!1,data:"ACK"},f&&f.readyState===f.OPEN&&f.send(JSON.stringify(l),function(e){e&&(d._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Error WS Offline Ack Each"),d.unsubscribeWS(f))}),c.shift(),c.shift(),c.shift(),c.shift(),_=c.shift(),h=(0,mongo_manager_1.objectIdHexString)(),log_method_latency_collection_1.LogMethodLatencies.create({_id:h,__v:0,date_start:new Date,date_end:null,latency_ms:0,method:_}),"reportBuilderGetResults"!==_&&"reportBuilderGetDistinctValue"!==_&&"reportBuilderBuildTree"!==_&&"generatePDF"!==_&&"getWOOfflineData"!==_&&"countQuery"!==_&&"countWithQuery"!==_&&"countCollectionWithQuery"!==_&&"find"!==_&&"findOne"!==_&&"findWithOptions"!==_&&"getDrivers"!==_&&"processAirdropDistribution"!==_&&log_collection_1.Logs.insertOne({_id:(0,mongo_manager_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(c))<2e5?JSON.stringify(c,null,2):"Too Big",method:_,id_user:f.id_user||"",user:f.user||"",messageId:n,route:t}),!this._methodManager._methods[_])return[3,7];e.label=3;case 3:return e.trys.push([3,5,,6]),[4,(h=this._methodManager.callMethodInternal).call.apply(h,__spreadArray([Object.assign({},this._methodManager,{id_user:f.id_user,user:f.user,id_ws:f.id_socket}),_],c,!1))];case 4:return e.sent(),[3,6];case 5:return g=e.sent(),console.log(new Date,"Offline Error",JSON.stringify(g,null,2)),[3,6];case 6:return"updateDocumentOffline"!==_&&"updateDocumentPropsOffline"!==_||index_1.ResolveIOServer.getMongoManager().invalidateQueryCache(c[0]),[3,8];case 7:console.log("Offline - Could not find method: "+_),e.label=8;case 8:return a++,[3,2];case 9:return this._offlineUpdates.splice(this._offlineUpdates.map(function(e){return e.id_socket}).indexOf(f.id_socket),1),[3,11];case 10:this._msgQueue.splice(0,0,{ws:f,data:r}),e.label=11;case 11:return[2]}})})}).on("end",function(){u.unsubscribeWS(f),u._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","WS End")}).on("close",function(){u.unsubscribeWS(f),u._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","WS Close")}).on("error",function(e){u.unsubscribeWS(f),u._subscriptionManager.getEnableDebug()&&console.log(new Date,f.user,f.id_socket,"WS Error")})}),setInterval(function(){u._serverWSS.clients.forEach(function(e){e.pingTime&&2e4<=Date.now()-e.pingTime.getTime()&&(!1===e.isAlive?(e.retryCnt++,3<=e.retryCnt?u.unsubscribeWS(e):(e.pingTime=new Date,e.ping(function(){}))):(e.retryCnt=0,e.isAlive=!1,e.pingTime=new Date,e.ping(function(){})))})},2e4),setInterval(function(){if(!u._msgQueueRunning&&u._msgQueue.length){u._msgQueueRunning=!0,u._debugMsgQueue+=1;var e=u._msgQueue.pop(),r=e.data,t=e.ws,e=r.shift(),n=r.shift(),s=r.shift(),o=r.shift();if("method"===o){var i=r.shift();if(t.user_readonly)return;var a=(0,mongo_manager_1.objectIdHexString)(),e=(log_method_latency_collection_1.LogMethodLatencies.create({_id:a,__v:0,date_start:new Date,date_end:null,latency_ms:0,method:i}),"reportBuilderGetResults"!==i&&"reportBuilderGetDistinctValue"!==i&&"reportBuilderBuildTree"!==i&&"generatePDF"!==i&&"getWOOfflineData"!==i&&"countQuery"!==i&&"countWithQuery"!==i&&"countCollectionWithQuery"!==i&&"find"!==i&&"findOne"!==i&&"findWithOptions"!==i&&"getDrivers"!==i&&"processAirdropDistribution"!==i&&log_collection_1.Logs.insertOne({_id:(0,mongo_manager_1.objectIdHexString)(),type:"client-request",collection:"",id_document:"",payload:(0,common_1.getBinarySize)(JSON.stringify(r))<2e5?JSON.stringify(r,null,2):"Too Big",method:i,id_user:t.id_user||"",user:t.user||"",messageId:s,route:e}),{messageId:s,hasError:!1,data:"ACK"});t&&t.readyState===t.OPEN&&t.send(JSON.stringify(e),function(e){e&&u.unsubscribeWS(t)}),u._methodManager._methods[i]?(e=u._methodManager).callMethod.apply(e,__spreadArray([a,t,n,s,i],r,!1)):console.log("Could not find method: "+i)}else"methodResponse"===o&&(i=r.shift(),method_response_collection_1.MethodResponses.findOne({$and:[{id_user:t.id_user},{message_id:s},{method:i},{date:n}]}).then(function(e){e&&t&&t.readyState===t.OPEN&&t.send(JSON.stringify(e.response),function(e){e&&u.unsubscribeWS(t)})},function(e){}));u._msgQueueRunning=!1}},1)},ResolveIOMainServer.prototype.unsubscribeWS=function(e){this._subscriptionManager.getEnableDebug()&&console.log(new Date,"Server App","Unsub WS",e.user,e.id_socket),this._subscriptionManager.unsubscribeAll(e),e.removeAllListeners()},ResolveIOMainServer.prototype.getApp=function(){return this._app},ResolveIOMainServer.prototype.getServerConfig=function(){return this._serverConfig},ResolveIOMainServer}();exports.default=ResolveIOMainServer;
2
2
  //# sourceMappingURL=server-app.js.map
package/server-app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server-app.ts"],"names":["http_1","require","express","bodyParser","xmlParser","WebSocket","jwt","moment","common_1","mongo_manager_1","cron_manager_1","method_manager_1","subscription_manager_1","monitor_manager_1","method_response_collection_1","log_collection_1","log_method_latency_collection_1","user_collection_1","home_1","auth_1","health_1","index_1","mongodb_1","worker_task_request_collection_1","worker_task_response_collection_1","ResolveIOMainServer","mainServer","serverConfig","clientRoutes","clientDir","sesMail","standardProgram","publicProgram","_this","this","_offlineUpdates","_msgQueue","_msgQueueRunning","_rebootFlag","LOGGER","_clientRoutes","_lastErrorMsg","_debugMsgRecv","_debugMsgQueue","_isWorkersEnabled","_isWorkerInstance","_safeShutdown","_serverConfig","_clientDir","_serverStartTime","Date","_monitorManager","MonitorManager","_monitorManagerFunction","MonitorManagerFunction","process","env","IS_WORKERS_ENABLED","IS_WORKER_INSTANCE","setInterval","_subscriptionManager","getEnableDebug","console","log","length","on","error","rej","__awaiter","diffTimeSec","diff","MongoNetworkTimeoutError","setTimeout","_methodManager","sendEmail","JSON","stringify","name","message","stack","_a","sent","exit","_serverHTTP","close","safeShutdown","MethodManager","_cronManager","CronManager","startWorkerInstance","startServerInstance","SubscriptionManager","_serverWSS","listen","prototype","_app","use","json","limit","reviver","dateReviver","urlencoded","extended","parameterLimit","_portHTTP","PORT_HTTP","_portWSS","PORT_WSS","createServer","req","res","next","setHeader","setupAuthRoutes","setupHealthRoutes","setupHomeRoutes","changeStream","WorkerTaskRequests","watchCollection","$match","fullDocument.status","fullDocument","change","operationType","task","processTask","find","status","sort","createdAt","pendingTasks","pendingTasks_1","_i","_id","findOneAndUpdate","$set","_b","callMethodInternal","call","apply","__spreadArray","Object","assign","id_user","user","id_ws","method","params","result","WorkerTaskResponses","create","id_request","has_error","data","err_1","updateOne","getActiveMonitorFunctions","setImmediate","ResolveIOServer","getMongoConnection","then","getIsWorkersEnabled","getIsWorkerInstance","getWS","Array","from","clients","filter","a","getWSList","forEach","ws","push","getWSUserList","getHTTPServer","getCronManager","getMethodManager","getSubscriptionManager","getMonitorManager","getRebootFlag","keepAliveTimeout","headersTimeout","Server","port","verifyClient","info","cb","infoData","headers","split","origin","token","verify","err","decoded","Users","findById","fullname","readonly","date","client","getClientName","objectIdHexString","createLoggedInUser","ping","duration","asMilliseconds","loggedInLatency","parseErrorFound","socketData","parse","e","readyState","OPEN","send","unsubscribeWS","messageRoute_1","some","includes","roles","groups","views","b","super_admin","messageDate","messageId","type","subType","pub","subscribe","slice","unsubscribe","serverRes","hasError","offlineUpdates","i","update","serverResMethod","shift","methodLatencyId","LogMethodLatencies","__v","date_start","date_end","latency_ms","Logs","insertOne","collection","id_document","payload","getBinarySize","route","_methods","err_3","getMongoManager","invalidateQueryCache","splice","map","indexOf","now","getTime","msg","pop","ws_1","messageRoute","callMethod","MethodResponses","findOne","$and","message_id","response","unsubscribeAll","removeAllListeners","getApp","getServerConfig"],"mappings":"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","file":"server-app.js","sourcesContent":["import { createServer, Server } from 'http';\nimport * as express from 'express';\nimport * as bodyParser from 'body-parser';\nimport * as xmlParser from 'express-xml-bodyparser';\nimport * as WebSocket from 'ws';\nimport * as jwt from 'jsonwebtoken';\n// import * as SegfaultHandler from 'segfault-handler';\nimport * as moment from 'moment-timezone';\n\nimport { dateReviver, getBinarySize, deepCopy } from './util/common';\n\nimport { objectIdHexString } from './managers/mongo.manager';\nimport { CronManager } from './managers/cron.manager';\nimport { MethodManager } from './managers/method.manager';\nimport { SubscriptionManager } from './managers/subscription.manager';\nimport { MonitorManager, MonitorManagerFunction } from './managers/monitor.manager';\n\nimport { ServerResponseModel } from './models/server-response.model';\n\nimport { MethodResponses } from './collections/method-response.collection';\nimport { Logs } from './collections/log.collection';\nimport { LogMethodLatencies } from './collections/log-method-latency.collection';\nimport { Users } from './collections/user.collection';\n\nimport { setupHomeRoutes } from './http/home';\nimport { setupAuthRoutes } from './http/auth';\nimport { setupHealthRoutes } from './http/health';\nimport { ResolveIOServer } from './index';\nimport { MongoNetworkTimeoutError } from 'mongodb';\nimport { WorkerTaskRequests } from './collections/worker-task-request.collection';\nimport { WorkerTaskResponses } from './collections/worker-task-response.collection';\n\nexport default class ResolveIOMainServer {\n\tprivate _app: express.Application;\n\tprivate _serverHTTP: Server;\n\tprivate _portHTTP: string | number;\n\tprivate _serverWSS: WebSocket.Server;\n\tprivate _portWSS: number;\n\tprivate _serverConfig;\n\tprivate _clientDir;\n\tprivate _offlineUpdates = [];\n\tprivate _msgQueue = [];\n\tprivate _msgQueueRunning = false;\n\tpublic sesMail = false;\n\tprivate standardProgram = false;\n\tprivate publicProgram = false;\n\tprivate _rebootFlag = false;\n\n\tprivate LOGGER = 'ERROR'; //ERROR / DEBUG\n\n\tprivate _monitorManager: MonitorManager;\n\tprivate _monitorManagerFunction: MonitorManagerFunction;\n\tprivate _subscriptionManager: SubscriptionManager;\n\tprivate _methodManager: MethodManager;\n\tprivate _cronManager: CronManager;\n\tprivate _clientRoutes: string[] = [];\n\n\tprivate _serverStartTime: Date;\n\tprivate _lastErrorMsg: Date = null;\n\n\tprivate _debugMsgRecv = 0;\n\tprivate _debugMsgQueue = 0;\n\n\tprivate _isWorkersEnabled = false;\n\tprivate _isWorkerInstance = false;\n\n\tprivate _safeShutdown = false;\n\n\tconstructor(mainServer, serverConfig, clientRoutes, clientDir, sesMail, standardProgram, publicProgram = false) {\n\t\tthis._serverConfig = serverConfig;\n\t\tthis._clientRoutes = clientRoutes;\n\t\tthis._clientDir = clientDir;\n\t\tthis.sesMail = sesMail;\n\t\tthis.standardProgram = standardProgram;\n\t\tthis.publicProgram = publicProgram;\n\n\t\tthis._serverStartTime = new Date();\n\t\tthis._lastErrorMsg = null;\n\t\tthis._monitorManager = new MonitorManager(mainServer, serverConfig);\n\t\tthis._monitorManagerFunction = new MonitorManagerFunction();\n\n\t\t// Check for workers and decide what to start\n\t\tthis._isWorkersEnabled = process.env.IS_WORKERS_ENABLED === 'true';\n\t\tthis._isWorkerInstance = process.env.IS_WORKER_INSTANCE === 'true';\n\n\t\tsetInterval(() => {\n\t\t\tif (this._subscriptionManager && this._subscriptionManager.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Queue Length', this._msgQueue.length);\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Recv Hits', this._debugMsgRecv);\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Queue Hits', this._debugMsgQueue);\n\t\t\t}\n\n\t\t\tthis._debugMsgQueue = 0;\n\t\t\tthis._debugMsgRecv = 0;\n\t\t}, 60000);\n\n\t\tprocess.on('unhandledRejection', async (error, rej) => {\n\t\t\t// Condition to filter out the MongoError with code 48 (NamespaceExists)\n\t\t\tif (error && error['name'] === 'MongoError' && error['code'] === 48) {\n\t\t\t\treturn; // Simply return without doing anything further\n\t\t\t}\n\n\t\t\tconsole.error(new Date(), 'Unhandled Rejection at Promise', [error, rej]);\n\t\t\t\n\t\t\tlet diffTimeSec = moment().diff(this._serverStartTime, 'seconds');\n\n\t\t\t// If this is a MongoNetworkTimeoutError, handle it specifically\n\t\t\tif (error && (error['name'] === 'MongoNetworkTimeoutError' || error instanceof MongoNetworkTimeoutError)) {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\t// Sending email notification (using your existing method)\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - MongoNetworkTimeoutError - Quitting NodeJS - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify({\n\t\t\t\t\t\tname: error['name'],\n\t\t\t\t\t\tmessage: error['message'],\n\t\t\t\t\t\tstack: error['stack']\n\t\t\t\t\t}, null, 2));\n\n\t\t\t\t\t// Exiting the process\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (error && error['name'] === 'MongoError' && error['message'] === 'not master') {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - Quitting NodeJS - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t}\n\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\telse if (error && error['name'] === 'MongoError' && error['message'] === 'not master and slaveOk=false') {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - Quitting NodeJS - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t}\n\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\telse if (error) {\n\t\t\t\tif (error['name'] !== 'StatusError' && error['message'] !== '') {\n\t\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t\t}, 60000);\n\n\t\t\t\t\t\tthis._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tprocess.on('uncaughtException', async error => {\n\t\t\tconsole.error(error, 'Uncaught Exception thrown');\n\n\t\t\tlet diffTimeSec = moment().diff(this._serverStartTime, 'seconds');\n\n\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t}, 60000);\n\t\t\t\t\n\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Exception - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t}\n\t\t});\n\n\t\t//PM2 wants to reboot/restart\n\t\tprocess.on('SIGINT', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tthis._serverHTTP.close();\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tprocess.on('SIGTERM', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tthis._serverHTTP.close();\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tprocess.on('SIGQUIT', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tthis._serverHTTP.close();\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Starting ResolveIO Server');\n\t\t}\n\n if (this._isWorkersEnabled) {\n if (this._isWorkerInstance) {\n console.log('Running as a Worker instance');\n\t\t\t\tthis._methodManager = new MethodManager(this, this._serverConfig, this._clientDir, this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n this._cronManager = new CronManager(this);\n\t\t\t\tthis.startWorkerInstance();\n }\n\t\t\telse {\n console.log('Running as a Server instance');\n this.startServerInstance(serverConfig);\n\t\t\t\tthis._methodManager = new MethodManager(this, this._serverConfig, this._clientDir, this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\t\tthis._subscriptionManager = new SubscriptionManager(this, this._serverWSS, this._serverConfig, this._monitorManagerFunction);\n\t\t\t\tthis.listen();\n }\n }\n\t\telse {\n console.log('Running with Workers Disabled');\n this.startServerInstance(serverConfig);\n\t\t\tthis._methodManager = new MethodManager(this, this._serverConfig, this._clientDir, this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\tthis._subscriptionManager = new SubscriptionManager(this, this._serverWSS, this._serverConfig, this._monitorManagerFunction);\n this._cronManager = new CronManager(this);\n\t\t\tthis.listen();\n }\n\t}\n\n\tprivate startServerInstance(serverConfig) {\n\t\t// Start express app\n\t\tthis._app = express();\n\n\t\t// Use body parser for http call (login)\n\t\tthis._app.use(bodyParser.json({limit: '50mb', reviver: dateReviver}));\n\t\tthis._app.use(bodyParser.urlencoded({limit: '50mb', extended: true, parameterLimit: 1000000 }));\n\t\tthis._app.use(xmlParser());\n\t\t\n\t\t// Set port\n\t\tthis._portHTTP = process.env.PORT_HTTP || serverConfig['PORT_HTTP'] || 8080;\n\t\tthis._portWSS = process.env.PORT_WSS || serverConfig['PORT_WSS'] || 8081;\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup ports');\n\t\t}\n\n\t\t// Create http server and websock server\n\t\tthis.createServer();\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Create server');\n\t\t}\n\n\t\t// Set CORS\n\t\tthis._app.use(function (req, res, next) {\n\n\t\t\t// Website you wish to allow to connect\n\t\t\t// res.setHeader('Access-Control-Allow-Origin', serverConfig['ROOT_URL']);\n\t\t\tres.setHeader('Access-Control-Allow-Origin', '*');\n\n\t\t\t// Request methods you wish to allow\n\t\t\t// res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');\n\t\t\tres.setHeader('Access-Control-Allow-Methods', 'GET, POST');\n\n\t\t\t// Request headers you wish to allow\n\t\t\tres.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');\n\n\t\t\t// Set to true if you need the website to include cookies in the requests sent\n\t\t\t// to the API (e.g. in case you use sessions)\n\t\t\tres.setHeader('Access-Control-Allow-Credentials', 'false');\n\n\t\t\t// Pass to next layer of middleware\n\t\t\tnext();\n\t\t});\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup cors');\n\t\t}\n\n\t\t// Set up http login route\n\t\tsetupAuthRoutes(this, this._app, serverConfig);\n\t\tsetupHealthRoutes(this._app, serverConfig);\n\n\t\tif (serverConfig['CLIENT_NAME'] === 'ResolveIO' || this.standardProgram) {\n\t\t\tsetupHomeRoutes(this, this._app, serverConfig);\n\t\t}\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup express routes');\n\t\t}\n\t}\n\n\tprivate async startWorkerInstance() {\n\t\tconsole.log('Worker instance started, watching worker-task-reqs...');\n\t\n\t\t// Now, set up the change stream to watch for new tasks\n\t\tlet changeStream = WorkerTaskRequests.watchCollection([{ $match: { 'fullDocument.status': 'pending' } }], { fullDocument: 'updateLookup' });\n\t\n\t\tchangeStream.on('change', async (change) => {\n\t\t\tif (change.operationType === 'insert') {\n\t\t\t\tconst task = change.fullDocument;\n\t\n\t\t\t\tif (task) {\n\t\t\t\t\t// console.log('Worker processing new task:', task._id);\n\t\t\t\t\tawait this.processTask(task);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\n\t\tchangeStream.on('error', (error) => {\n\t\t\tconsole.error('Error in change stream worker task requests:', error);\n\t\t\tchangeStream.close();\n\t\t\tsetTimeout(() => this.startWorkerInstance(), 5000); // Restart after a delay\n\t\t});\n\t\n\t\tchangeStream.on('close', () => {\n\t\t\tconsole.log('Change stream worker task requests closed. Restarting...');\n\t\t\tsetTimeout(() => this.startWorkerInstance(), 5000); // Restart after a delay\n\t\t});\n\n\t\t// First, process any existing pending tasks in the database\n\t\tconst pendingTasks = await WorkerTaskRequests.find({ status: 'pending' }, {sort: {createdAt: 1}});\n\n\t\tfor (const task of pendingTasks) {\n\t\t\tconsole.log('Processing existing pending task:', task._id);\n\t\t\tawait this.processTask(task);\n\t\t}\n\t}\n\t\n\t// Process a task (handles both existing and new tasks)\n\tprivate async processTask(task) {\n\t\t// Update the task status to 'processing'\n\t\tlet req = await WorkerTaskRequests.findOneAndUpdate({ _id: task._id, status: 'pending' }, { $set: { status: 'processing' } });\n\n\t\tif (req) {\n\t\t\ttry {\n\t\t\t\t// Run the actual method\n\t\t\t\tconst result = await this._methodManager.callMethodInternal.call(Object.assign({}, this._methodManager, { id_user: task.id_user, user: task.user, id_ws: task.id_ws }), task.method, ...task.params);\n\n\t\t\t\tWorkerTaskResponses.create({\n\t\t\t\t\tid_request: task._id,\n\t\t\t\t\thas_error: false,\n\t\t\t\t\tdata: result,\n\t\t\t\t\tid_user: task.id_user,\n\t\t\t\t\tuser: task.user,\n\t\t\t\t\tid_ws: task.id_ws\n\t\t\t\t});\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\tconsole.error('Worker failed to process task:', task._id, err);\n\n\t\t\t\tWorkerTaskResponses.create({\n\t\t\t\t\tid_request: task._id,\n\t\t\t\t\thas_error: true,\n\t\t\t\t\tdata: err.message,\n\t\t\t\t\tid_user: task.id_user,\n\t\t\t\t\tuser: task.user,\n\t\t\t\t\tid_ws: task.id_ws\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Mark the task as complete\n\t\t\tWorkerTaskRequests.updateOne({ _id: task._id }, { $set: { status: 'complete' } });\n\t\t}\n\t}\n\n\tprivate safeShutdown() {\n\t\tif (!this._safeShutdown) {\n\t\t\tconsole.log(new Date(), 'Safe Shutdown Command Received');\n\t\t}\n\n\t\tif (\n\t\t\t!this._monitorManagerFunction.getActiveMonitorFunctions().length && \n\t\t\t// (!this._monitorManagerFunction.getLastCompletedMonitorFunction() ||\n\t\t\t// Date.now() >= this._monitorManagerFunction.getLastCompletedMonitorFunction().endTime.getTime() + 1500) &&\n\t\t\t!this._msgQueue.length &&\n\t\t\t!this._msgQueueRunning &&\n\t\t\t!this._offlineUpdates.length\n\t\t) {\n\t\t\tResolveIOServer.getMongoConnection().close(false).then(() => {\n\t\t\t\tconsole.log(new Date(), 'Safe Exit Complete, Process Exit');\n\t\t\t\tprocess.exit(0);\n\t\t\t}, () => {process.exit(1)});\n\t\t}\n\t\telse {\n\t\t\tif (!this._safeShutdown) {\n\t\t\t\tthis._safeShutdown = true;\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._safeShutdown = false;\n\t\t\t\t}, 1000);\n\n\t\t\t\tconsole.log(new Date(), \n\t\t\t\t\t'Safe Exit In Progress', \n\t\t\t\t\tthis._monitorManagerFunction.getActiveMonitorFunctions().length, \n\t\t\t\t\t// this._monitorManagerFunction.getLastCompletedMonitorFunction() ? this._monitorManagerFunction.getLastCompletedMonitorFunction().endTime : '',\n\t\t\t\t\tthis._msgQueue.length, \n\t\t\t\t\tthis._msgQueueRunning,\n\t\t\t\t\tthis._offlineUpdates.length\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsetImmediate(() => {\n\t\t\t\tthis.safeShutdown();\n\t\t\t});\n\t\t}\n\t}\n\n\tgetIsWorkersEnabled() {\n\t\treturn this._isWorkersEnabled;\n\t}\n\n\tgetIsWorkerInstance() {\n\t\treturn this._isWorkerInstance;\n\t}\n\n\tpublic getWS(id_ws: string) {\n\t\treturn Array.from(this._serverWSS.clients).filter(a => a['id_socket'] === id_ws)[0];\n\t}\n\n\tpublic getWSList() {\n\t\tlet res = [];\n\n\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\tres.push(ws['id_socket']);\n\t\t});\n\n\t\treturn res;\n\t}\n\n\tpublic getWSUserList() {\n\t\tlet res = [];\n\n\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\tres.push(ws['id_user']);\n\t\t});\n\n\t\treturn res;\n\t}\n\n\tpublic getHTTPServer() {\n\t\treturn this._serverHTTP;\n\t}\n\n\tpublic getCronManager() {\n\t\treturn this._cronManager;\n\t}\n\n\tpublic getMethodManager() {\n\t\treturn this._methodManager;\n\t}\n\n\tpublic getSubscriptionManager() {\n\t\treturn this._subscriptionManager;\n\t}\n\n\tpublic getMonitorManager() {\n\t\treturn this._monitorManager;\n\t}\n\n\tpublic getRebootFlag() {\n\t\treturn this._rebootFlag;\n\t}\n\n\tprivate createServer(): void {\n\t\t// Start express server\n\t\tthis._serverHTTP = createServer(this._app);\n\t\tthis._serverHTTP.keepAliveTimeout = 65000;\n\t\tthis._serverHTTP.headersTimeout = 66000; // This should be bigger than `keepAliveTimeout + your server's expected response time`\n\n\t\t// Start websocket server\n\t\t// Verify client with token before opening socket\n\t\tthis._serverWSS = new WebSocket.Server({ \n\t\t\tport: this._portWSS,\n\t\t\tverifyClient: this.publicProgram ? null : async (info, cb) => {\n\t\t\t\tif (this._rebootFlag) {\n\t\t\t\t\tcb(false, 409, 'Unable To Process');\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\t\t\tconsole.log('Verify Client', info, cb);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet infoData = (<string>info.req.headers['sec-websocket-protocol']).split(/,/);\n\n\t\t\t\t\tif (info.origin !== this._serverConfig['ROOT_URL'] && info.origin !== this._serverConfig['SEC_ROOT_URL'] && info.origin !== this._serverConfig['RESOLVEIO_URL'] && info.origin !== this._serverConfig['RESOLVEIO_SECONDARY_URL']) {\n\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet token = infoData[0];\n\t\t\t\t\t\tif (!token) {\n\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tjwt.verify(token, this._serverConfig['JWT_SECRET'], async (err, decoded) => {\n\t\t\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tinfo.req['id_user'] = decoded['id_user'];\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tlet user = await Users.findById(decoded['id_user']);\n\t\t\t\t\t\t\t\t\t\tif (user) {\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['user'] = user.fullname;\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['user_readonly'] = user.readonly || false;\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['doc_user'] = user;\n\t\t\t\t\t\t\t\t\t\t\tcb(true);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\t\tcb(false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t\t\t\t\tcb(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t// Listen to port for websocket\n\tprivate listen(): void {\n\t\tthis._serverHTTP.listen(this._portHTTP, () => {\n\t\t\tconsole.log('Running server on port %s', this._portHTTP);\n\t\t});\n\n\t\tthis._serverWSS.on('listening', () => {\n\t\t\tconsole.log('Running server on port %s', this._portWSS);\n\t\t});\n\n\t\t// On websocket connection (already verified)\n\t\tthis._serverWSS.on('connection', (ws, req) => {\n\t\t\tif (!this.publicProgram) {\n\t\t\t\t// Get user from token\n\t\t\t\tws['id_user'] = req['id_user'];\n\t\t\t\tws['user'] = req['user'];\n\t\t\t\tws['user_readonly'] = req['user_readonly'];\n\t\t\t\tws['doc_user'] = req['doc_user'];\n\n\t\t\t\tif (ws['user'] !== 'Admin' && this._serverConfig['CLIENT_NAME'] !== 'ResolveIO') {\n\t\t\t\t\tthis.getMethodManager().callMethodInternal.call(this.getMethodManager(), 'supportCreateBillingUser', {\n\t\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\t\tuser: ws['user'],\n\t\t\t\t\t\tdate: new Date(),\n\t\t\t\t\t\tclient: ResolveIOServer.getClientName()\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tws['id_socket'] = objectIdHexString();\n\t\t\tws['retryCnt'] = 0;\n\n\t\t\tthis._subscriptionManager.createLoggedInUser(ws['id_socket']).then(() => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\tws.ping(() => {});\n\t\t\t\t}, 5000);\n\t\t\t});\n\n\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\tconsole.log('Connection from: ' + req['user']);\n\t\t\t}\n\t\t\t\n\t\t\t// Use for keeping connection alive (ping/pong)\n\t\t\tws['isAlive'] = true;\n\t\t\tws.on('pong', () => {\n\t\t\t\tws['isAlive'] = true;\n\t\t\t\tws['pongTime'] = new Date();\n\t\t\t\tws['latency'] = moment.duration(moment(ws['pongTime']).diff(ws['pingTime'])).asMilliseconds();\n\t\t\t\tthis._subscriptionManager.loggedInLatency(ws);\n\t\t\t})\n\t\t\t.on('message', async (message: string) => {\n\t\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\t\tconsole.log('Message from: ' + ws['user'], message);\n\t\t\t\t}\n\n\t\t\t\tthis._debugMsgRecv += 1;\n\n\t\t\t\tlet parseErrorFound = false;\n\n\t\t\t\tlet socketData = [];\n\t\t\t\t\n\t\t\t\ttry {\n\t\t\t\t\tsocketData = JSON.parse(message, dateReviver);\n\t\t\t\t}\n\t\t\t\tcatch(e) {\n\t\t\t\t\tconsole.log('Error - JSON.parse', message);\n\t\t\t\t\t\n\t\t\t\t\tthis._methodManager.sendEmail('dev@resolveio.com', 'SERVER - JSON Parse Error - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([message, e]));\n\n\t\t\t\t\tparseErrorFound = true;\n\t\t\t\t}\n\n\t\t\t\tif (!parseErrorFound) {\n\t\t\t\t\tif (socketData[0] === 'ping') {\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tws.send('pong', (error) => {\n\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Pong');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet messageRoute = socketData[0];\n\n\t\t\t\t\tif (!this.publicProgram && this._clientRoutes.some(a => messageRoute.includes(a)) && !ws['doc_user'].roles.groups.some(a => a.views.some(b => messageRoute.includes(b) || b.includes(messageRoute))) && !ws['doc_user'].roles.super_admin) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet messageDate = socketData[1];\n\t\t\t\t\tlet messageId = socketData[2]\n\t\t\t\t\tlet type = socketData[3]\n\n\t\t\t\t\tif (type === 'subscription') {\n\t\t\t\t\t\tlet subType = socketData[4];\n\t\t\t\t\t\tlet pub = socketData[5];\n\t\t\n\t\t\t\t\t\t// Subscribe\n\t\t\t\t\t\tif (subType === 'sub') {\n\t\t\t\t\t\t\tthis._subscriptionManager.subscribe(messageRoute, messageDate, ws, messageId, pub, socketData.slice(6));\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Unsubscribe\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis._subscriptionManager.unsubscribe(messageRoute, messageDate, ws, messageId, pub, socketData.slice(6));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (!this.publicProgram && type === 'offline') {\n\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\tdata: 'ACK'\n\t\t\t\t\t\t};\n\t\t\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tws.send(JSON.stringify(serverRes), (error) => {\n\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Offline Ack Main');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._offlineUpdates.push(ws);\n\t\t\t\t\t\tlet offlineUpdates = socketData[4];\n\n\t\t\t\t\t\tfor (let i = 0; i < offlineUpdates.length; i++) {\n\t\t\t\t\t\t\tlet update = offlineUpdates[i];\n\t\t\t\t\t\t\tlet data = update.data;\n\n\t\t\t\t\t\t\tlet serverResMethod: ServerResponseModel = {\n\t\t\t\t\t\t\t\tmessageId: update.data[2],\n\t\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\t\tdata: 'ACK'\n\t\t\t\t\t\t\t};\n\t\t\t\n\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\tws.send(JSON.stringify(serverResMethod), (error) => {\n\t\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Offline Ack Each');\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlet updateRoute = data.shift();\n\t\t\t\t\t\t\tlet updateDate = data.shift();\n\t\t\t\t\t\t\tlet updateMessageId = data.shift();\n\t\t\t\t\t\t\tlet updateType = data.shift();\n\t\t\t\t\t\t\tlet method = data.shift();\n\t\t\t\t\t\t\tlet methodLatencyId = objectIdHexString();\n\n\t\t\t\t\t\t\tLogMethodLatencies.create({\n\t\t\t\t\t\t\t\t_id: methodLatencyId,\n\t\t\t\t\t\t\t\t__v: 0,\n\t\t\t\t\t\t\t\tdate_start: new Date(),\n\t\t\t\t\t\t\t\tdate_end: null,\n\t\t\t\t\t\t\t\tlatency_ms: 0,\n\t\t\t\t\t\t\t\tmethod: method\n\t\t\t\t\t\t\t});\n\t\t\t\n\t\t\t\t\t\t\tif (method !== 'reportBuilderGetResults' && method !== 'reportBuilderGetDistinctValue' && method !== 'reportBuilderBuildTree' && method !== 'generatePDF' && method !== 'getWOOfflineData' && method !== 'countQuery' && method !== 'countWithQuery' && method !== 'countCollectionWithQuery' && method !== 'find' && method !== 'findOne' && method !== 'findWithOptions' && method !== 'getDrivers' && method !== 'processAirdropDistribution') {\n\t\t\t\t\t\t\t\tLogs.insertOne({\n\t\t\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(data)) < 200000 ? JSON.stringify(data, null, 2) : 'Too Big',\n\t\t\t\t\t\t\t\t\tmethod: method,\n\t\t\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\t\t\troute: messageRoute\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (this._methodManager._methods[method]) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait this._methodManager.callMethodInternal.call(Object.assign({}, this._methodManager, {id_user: ws['id_user'], user: ws['user'], id_ws: ws['id_socket']}), method, ...data);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Offline Error', JSON.stringify(err, null, 2));\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (method === 'updateDocumentOffline' || method === 'updateDocumentPropsOffline') {\n\t\t\t\t\t\t\t\t\tResolveIOServer.getMongoManager().invalidateQueryCache(data[0]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tconsole.log('Offline - Could not find method: ' + method);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._offlineUpdates.splice(this._offlineUpdates.map(a => a['id_socket']).indexOf(ws['id_socket']), 1);\n\t\t\t\t\t}\n\t\t\t\t\telse { //methods\n\t\t\t\t\t\tthis._msgQueue.splice(0, 0, {\n\t\t\t\t\t\t\tws: ws,\n\t\t\t\t\t\t\tdata: socketData\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('end', () => {\n\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\tconsole.log(new Date(), 'Server App', 'WS End');\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('close', () => {\n\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\tconsole.log(new Date(), 'Server App', 'WS Close');\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('error', error => {\n\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\tconsole.log(new Date(), ws['user'], ws['id_socket'], 'WS Error');\n\t\t\t\t}\n\t\t\t\t\n\t\t\t});\n\t\t});\n\n\t\t// Keep alive timer to ping/pong\n\t\tsetInterval(() => {\n\t\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\t\tif (ws['pingTime'] && Date.now() - ws['pingTime'].getTime() >= 20000) {\n\t\t\t\t\tif (ws['isAlive'] === false) {\n\t\t\t\t\t\tws['retryCnt']++;\n\n\t\t\t\t\t\tif (ws['retryCnt'] >= 3) {\n\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\t\tws.ping(() => {});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tws['retryCnt'] = 0;\n\t\t\t\t\t\tws['isAlive'] = false;\n\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\tws.ping(() => {});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}, 20000);\n\n\t\tsetInterval(() => {\n\t\t\tif (!this._msgQueueRunning) {\t\t\t\t\n\t\t\t\tif (this._msgQueue.length) {\n\t\t\t\t\tthis._msgQueueRunning = true;\n\t\t\t\t\tthis._debugMsgQueue += 1;\n\n\t\t\t\t\tlet msg = this._msgQueue.pop();\n\t\t\t\t\tlet data = msg.data;\n\t\t\t\t\tlet ws = msg.ws;\n\t\t\n\t\t\t\t\tlet messageRoute: string = data.shift();\n\t\t\t\t\tlet messageDate: Date = data.shift();\n\t\t\t\t\tlet messageId: number = data.shift();\n\t\t\t\t\tlet type: string = data.shift();\n\t\t\n\t\t\t\t\t// Method call\n\t\t\t\t\tif (type === 'method') {\n\t\t\t\t\t\tlet method = data.shift();\n\n\t\t\t\t\t\tif (ws['user_readonly']) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet methodLatencyId = objectIdHexString();\n\n\t\t\t\t\t\tLogMethodLatencies.create({\n\t\t\t\t\t\t\t_id: methodLatencyId,\n\t\t\t\t\t\t\t__v: 0,\n\t\t\t\t\t\t\tdate_start: new Date(),\n\t\t\t\t\t\t\tdate_end: null,\n\t\t\t\t\t\t\tlatency_ms: 0,\n\t\t\t\t\t\t\tmethod: method\n\t\t\t\t\t\t});\n\t\t\n\t\t\t\t\t\tif (method !== 'reportBuilderGetResults' && method !== 'reportBuilderGetDistinctValue' && method !== 'reportBuilderBuildTree' && method !== 'generatePDF' && method !== 'getWOOfflineData' && method !== 'countQuery' && method !== 'countWithQuery' && method !== 'countCollectionWithQuery' && method !== 'find' && method !== 'findOne' && method !== 'findWithOptions' && method !== 'getDrivers' && method !== 'processAirdropDistribution') {\n\t\t\t\t\t\t\tLogs.insertOne({\n\t\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(data)) < 200000 ? JSON.stringify(data, null, 2) : 'Too Big',\n\t\t\t\t\t\t\t\tmethod: method,\n\t\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\t\troute: messageRoute\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\n\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\tdata: 'ACK'\n\t\t\t\t\t\t};\n\t\t\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tws.send(JSON.stringify(serverRes), (error) => {\n\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\n\t\t\t\t\t\tif (this._methodManager._methods[method]) {\n\t\t\t\t\t\t\tthis._methodManager.callMethod(methodLatencyId, ws, messageDate, messageId, method, ...data);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tconsole.log('Could not find method: ' + method);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (type === 'methodResponse') {\n\t\t\t\t\t\tlet method = data.shift();\n\t\t\n\t\t\t\t\t\tMethodResponses.findOne({$and: [\n\t\t\t\t\t\t\t{id_user: ws['id_user']}, \n\t\t\t\t\t\t\t{message_id: messageId},\n\t\t\t\t\t\t\t{method: method},\n\t\t\t\t\t\t\t{date: messageDate}\n\t\t\t\t\t\t]}).then(res => {\n\t\t\t\t\t\t\tif (res) {\n\t\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\t\tws.send(JSON.stringify(res.response), (error) => {\n\t\t\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, err => {});\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tthis._msgQueueRunning = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}, 1);\n\t}\n\n\tpublic unsubscribeWS(ws: WebSocket) {\n\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\tconsole.log(new Date(), 'Server App', 'Unsub WS', ws['user'], ws['id_socket']);\n\t\t}\n\t\tthis._subscriptionManager.unsubscribeAll(ws);\n\t\tws.removeAllListeners();\n\t\tws = null;\n\t}\n\n\tpublic getApp() {\n\t\treturn this._app;\n\t}\n\n\tpublic getServerConfig() {\n\t\treturn this._serverConfig;\n\t}\n}"]}
1
+ {"version":3,"sources":["../../src/server-app.ts"],"names":["http_1","require","express","bodyParser","xmlParser","WebSocket","jwt","moment","common_1","mongo_manager_1","cron_manager_1","method_manager_1","subscription_manager_1","monitor_manager_1","method_response_collection_1","log_collection_1","log_method_latency_collection_1","user_collection_1","home_1","auth_1","health_1","index_1","mongodb_1","worker_task_request_collection_1","worker_task_response_collection_1","ResolveIOMainServer","mainServer","serverConfig","clientRoutes","clientDir","sesMail","standardProgram","publicProgram","_this","this","_offlineUpdates","_msgQueue","_msgQueueRunning","_rebootFlag","LOGGER","_clientRoutes","_lastErrorMsg","_debugMsgRecv","_debugMsgQueue","_isWorkersEnabled","_isWorkerInstance","_workerTasks","_safeShutdown","_serverConfig","_clientDir","_serverStartTime","Date","_monitorManager","MonitorManager","_monitorManagerFunction","MonitorManagerFunction","process","env","IS_WORKERS_ENABLED","IS_WORKER_INSTANCE","setInterval","_subscriptionManager","getEnableDebug","console","log","length","on","error","rej","__awaiter","diffTimeSec","diff","MongoNetworkTimeoutError","setTimeout","_methodManager","sendEmail","JSON","stringify","name","message","stack","_a","sent","exit","_serverHTTP","close","safeShutdown","MethodManager","_cronManager","CronManager","startWorkerInstance","startServerInstance","SubscriptionManager","_serverWSS","listen","prototype","_app","use","json","limit","reviver","dateReviver","urlencoded","extended","parameterLimit","_portHTTP","PORT_HTTP","_portWSS","PORT_WSS","createServer","req","res","next","setHeader","setupAuthRoutes","setupHealthRoutes","setupHomeRoutes","changeStream","WorkerTaskRequests","watchCollection","$match","fullDocument.status","fullDocument","change","operationType","task_1","processTask","find","status","sort","createdAt","pendingTasks","pendingTasks_1","_i","task","_id","updateOne","$set","then","resReq","push","callMethodInternal","call","apply","__spreadArray","Object","assign","id_user","user","id_ws","method","params","result","_b","includes","splice","indexOf","WorkerTaskResponses","create","id_request","has_error","data","err_1","getActiveMonitorFunctions","setImmediate","ResolveIOServer","getMongoConnection","getIsWorkersEnabled","getIsWorkerInstance","getWS","Array","from","clients","filter","a","getWSList","forEach","ws","getWSUserList","getHTTPServer","getCronManager","getMethodManager","getSubscriptionManager","getMonitorManager","getRebootFlag","keepAliveTimeout","headersTimeout","Server","port","verifyClient","info","cb","infoData","headers","split","origin","token","verify","err","decoded","Users","findById","fullname","readonly","date","client","getClientName","objectIdHexString","createLoggedInUser","ping","duration","asMilliseconds","loggedInLatency","parseErrorFound","socketData","parse","e","readyState","OPEN","send","unsubscribeWS","messageRoute_1","some","roles","groups","views","b","super_admin","messageDate","messageId","type","subType","pub","subscribe","slice","unsubscribe","serverRes","hasError","offlineUpdates","i","update","serverResMethod","shift","methodLatencyId","LogMethodLatencies","__v","date_start","date_end","latency_ms","Logs","insertOne","collection","id_document","payload","getBinarySize","route","_methods","err_3","getMongoManager","invalidateQueryCache","map","now","getTime","msg","pop","ws_1","messageRoute","callMethod","MethodResponses","findOne","$and","message_id","response","unsubscribeAll","removeAllListeners","getApp","getServerConfig"],"mappings":"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","file":"server-app.js","sourcesContent":["import { createServer, Server } from 'http';\nimport * as express from 'express';\nimport * as bodyParser from 'body-parser';\nimport * as xmlParser from 'express-xml-bodyparser';\nimport * as WebSocket from 'ws';\nimport * as jwt from 'jsonwebtoken';\n// import * as SegfaultHandler from 'segfault-handler';\nimport * as moment from 'moment-timezone';\n\nimport { dateReviver, getBinarySize, deepCopy } from './util/common';\n\nimport { objectIdHexString } from './managers/mongo.manager';\nimport { CronManager } from './managers/cron.manager';\nimport { MethodManager } from './managers/method.manager';\nimport { SubscriptionManager } from './managers/subscription.manager';\nimport { MonitorManager, MonitorManagerFunction } from './managers/monitor.manager';\n\nimport { ServerResponseModel } from './models/server-response.model';\n\nimport { MethodResponses } from './collections/method-response.collection';\nimport { Logs } from './collections/log.collection';\nimport { LogMethodLatencies } from './collections/log-method-latency.collection';\nimport { Users } from './collections/user.collection';\n\nimport { setupHomeRoutes } from './http/home';\nimport { setupAuthRoutes } from './http/auth';\nimport { setupHealthRoutes } from './http/health';\nimport { ResolveIOServer } from './index';\nimport { MongoNetworkTimeoutError } from 'mongodb';\nimport { WorkerTaskRequests } from './collections/worker-task-request.collection';\nimport { WorkerTaskResponses } from './collections/worker-task-response.collection';\n\nexport default class ResolveIOMainServer {\n\tprivate _app: express.Application;\n\tprivate _serverHTTP: Server;\n\tprivate _portHTTP: string | number;\n\tprivate _serverWSS: WebSocket.Server;\n\tprivate _portWSS: number;\n\tprivate _serverConfig;\n\tprivate _clientDir;\n\tprivate _offlineUpdates = [];\n\tprivate _msgQueue = [];\n\tprivate _msgQueueRunning = false;\n\tpublic sesMail = false;\n\tprivate standardProgram = false;\n\tprivate publicProgram = false;\n\tprivate _rebootFlag = false;\n\n\tprivate LOGGER = 'ERROR'; //ERROR / DEBUG\n\n\tprivate _monitorManager: MonitorManager;\n\tprivate _monitorManagerFunction: MonitorManagerFunction;\n\tprivate _subscriptionManager: SubscriptionManager;\n\tprivate _methodManager: MethodManager;\n\tprivate _cronManager: CronManager;\n\tprivate _clientRoutes: string[] = [];\n\n\tprivate _serverStartTime: Date;\n\tprivate _lastErrorMsg: Date = null;\n\n\tprivate _debugMsgRecv = 0;\n\tprivate _debugMsgQueue = 0;\n\n\tprivate _isWorkersEnabled = false;\n\tprivate _isWorkerInstance = false;\n\tprivate _workerTasks = [];\n\n\tprivate _safeShutdown = false;\n\n\tconstructor(mainServer, serverConfig, clientRoutes, clientDir, sesMail, standardProgram, publicProgram = false) {\n\t\tthis._serverConfig = serverConfig;\n\t\tthis._clientRoutes = clientRoutes;\n\t\tthis._clientDir = clientDir;\n\t\tthis.sesMail = sesMail;\n\t\tthis.standardProgram = standardProgram;\n\t\tthis.publicProgram = publicProgram;\n\n\t\tthis._serverStartTime = new Date();\n\t\tthis._lastErrorMsg = null;\n\t\tthis._monitorManager = new MonitorManager(mainServer, serverConfig);\n\t\tthis._monitorManagerFunction = new MonitorManagerFunction();\n\n\t\t// Check for workers and decide what to start\n\t\tthis._isWorkersEnabled = process.env.IS_WORKERS_ENABLED === 'true';\n\t\tthis._isWorkerInstance = process.env.IS_WORKER_INSTANCE === 'true';\n\n\t\tsetInterval(() => {\n\t\t\tif (this._subscriptionManager && this._subscriptionManager.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Queue Length', this._msgQueue.length);\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Recv Hits', this._debugMsgRecv);\n\t\t\t\tconsole.log(new Date(), 'Server App', 'Msg Queue Hits', this._debugMsgQueue);\n\t\t\t}\n\n\t\t\tthis._debugMsgQueue = 0;\n\t\t\tthis._debugMsgRecv = 0;\n\t\t}, 60000);\n\n\t\tprocess.on('unhandledRejection', async (error, rej) => {\n\t\t\t// Condition to filter out the MongoError with code 48 (NamespaceExists)\n\t\t\tif (error && error['name'] === 'MongoError' && error['code'] === 48) {\n\t\t\t\treturn; // Simply return without doing anything further\n\t\t\t}\n\n\t\t\tconsole.error(new Date(), 'Unhandled Rejection at Promise', [error, rej]);\n\t\t\t\n\t\t\tlet diffTimeSec = moment().diff(this._serverStartTime, 'seconds');\n\n\t\t\t// If this is a MongoNetworkTimeoutError, handle it specifically\n\t\t\tif (error && (error['name'] === 'MongoNetworkTimeoutError' || error instanceof MongoNetworkTimeoutError)) {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\t// Sending email notification (using your existing method)\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - MongoNetworkTimeoutError - Quitting NodeJS - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify({\n\t\t\t\t\t\tname: error['name'],\n\t\t\t\t\t\tmessage: error['message'],\n\t\t\t\t\t\tstack: error['stack']\n\t\t\t\t\t}, null, 2));\n\n\t\t\t\t\t// Exiting the process\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (error && error['name'] === 'MongoError' && error['message'] === 'not master') {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - Quitting NodeJS - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t}\n\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\telse if (error && error['name'] === 'MongoError' && error['message'] === 'not master and slaveOk=false') {\n\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t}, 60000);\n\n\t\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - Quitting NodeJS - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t}\n\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\telse if (error) {\n\t\t\t\tif (error['name'] !== 'StatusError' && error['message'] !== '') {\n\t\t\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t\t\t}, 60000);\n\n\t\t\t\t\t\tthis._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Rejection - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tprocess.on('uncaughtException', async error => {\n\t\t\tconsole.error(error, 'Uncaught Exception thrown');\n\n\t\t\tlet diffTimeSec = moment().diff(this._serverStartTime, 'seconds');\n\n\t\t\tif (diffTimeSec > 60 && !this._lastErrorMsg) {\n\t\t\t\tthis._lastErrorMsg = new Date();\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._lastErrorMsg = null;\n\t\t\t\t}, 60000);\n\t\t\t\t\n\t\t\t\tawait this._methodManager.sendEmail('dev@resolveio.com', 'SERVER - Unhandled Exception - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([error['name'], error['message'], error['stack']], null, 2));\n\t\t\t}\n\t\t});\n\n\t\t//PM2 wants to reboot/restart\n\t\tprocess.on('SIGINT', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tthis._serverHTTP.close();\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tprocess.on('SIGTERM', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tthis._serverHTTP.close();\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tprocess.on('SIGQUIT', () => {\n\t\t\tthis._rebootFlag = true;\n\t\t\tthis._serverHTTP.close();\n\t\t\tthis.safeShutdown();\n\t\t});\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Starting ResolveIO Server');\n\t\t}\n\n if (this._isWorkersEnabled) {\n if (this._isWorkerInstance) {\n console.log('Running as a Worker instance');\n\t\t\t\tthis._methodManager = new MethodManager(this, this._serverConfig, this._clientDir, this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n this._cronManager = new CronManager(this);\n\t\t\t\tthis.startWorkerInstance();\n }\n\t\t\telse {\n console.log('Running as a Server instance');\n this.startServerInstance(serverConfig);\n\t\t\t\tthis._methodManager = new MethodManager(this, this._serverConfig, this._clientDir, this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\t\tthis._subscriptionManager = new SubscriptionManager(this, this._serverWSS, this._serverConfig, this._monitorManagerFunction);\n\t\t\t\tthis.listen();\n }\n }\n\t\telse {\n console.log('Running with Workers Disabled');\n this.startServerInstance(serverConfig);\n\t\t\tthis._methodManager = new MethodManager(this, this._serverConfig, this._clientDir, this._monitorManagerFunction, this._isWorkersEnabled, this._isWorkerInstance);\n\t\t\tthis._subscriptionManager = new SubscriptionManager(this, this._serverWSS, this._serverConfig, this._monitorManagerFunction);\n this._cronManager = new CronManager(this);\n\t\t\tthis.listen();\n }\n\t}\n\n\tprivate startServerInstance(serverConfig) {\n\t\t// Start express app\n\t\tthis._app = express();\n\n\t\t// Use body parser for http call (login)\n\t\tthis._app.use(bodyParser.json({limit: '50mb', reviver: dateReviver}));\n\t\tthis._app.use(bodyParser.urlencoded({limit: '50mb', extended: true, parameterLimit: 1000000 }));\n\t\tthis._app.use(xmlParser());\n\t\t\n\t\t// Set port\n\t\tthis._portHTTP = process.env.PORT_HTTP || serverConfig['PORT_HTTP'] || 8080;\n\t\tthis._portWSS = process.env.PORT_WSS || serverConfig['PORT_WSS'] || 8081;\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup ports');\n\t\t}\n\n\t\t// Create http server and websock server\n\t\tthis.createServer();\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Create server');\n\t\t}\n\n\t\t// Set CORS\n\t\tthis._app.use(function (req, res, next) {\n\n\t\t\t// Website you wish to allow to connect\n\t\t\t// res.setHeader('Access-Control-Allow-Origin', serverConfig['ROOT_URL']);\n\t\t\tres.setHeader('Access-Control-Allow-Origin', '*');\n\n\t\t\t// Request methods you wish to allow\n\t\t\t// res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');\n\t\t\tres.setHeader('Access-Control-Allow-Methods', 'GET, POST');\n\n\t\t\t// Request headers you wish to allow\n\t\t\tres.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');\n\n\t\t\t// Set to true if you need the website to include cookies in the requests sent\n\t\t\t// to the API (e.g. in case you use sessions)\n\t\t\tres.setHeader('Access-Control-Allow-Credentials', 'false');\n\n\t\t\t// Pass to next layer of middleware\n\t\t\tnext();\n\t\t});\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup cors');\n\t\t}\n\n\t\t// Set up http login route\n\t\tsetupAuthRoutes(this, this._app, serverConfig);\n\t\tsetupHealthRoutes(this._app, serverConfig);\n\n\t\tif (serverConfig['CLIENT_NAME'] === 'ResolveIO' || this.standardProgram) {\n\t\t\tsetupHomeRoutes(this, this._app, serverConfig);\n\t\t}\n\n\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\tconsole.log('Setup express routes');\n\t\t}\n\t}\n\n\tprivate async startWorkerInstance() {\n\t\tconsole.log('Worker instance started, watching worker-task-reqs...');\n\t\n\t\t// Now, set up the change stream to watch for new tasks\n\t\tlet changeStream = WorkerTaskRequests.watchCollection([{ $match: { 'fullDocument.status': 'pending' } }], { fullDocument: 'updateLookup' });\n\t\n\t\tchangeStream.on('change', async (change) => {\n\t\t\tif (change.operationType === 'insert') {\n\t\t\t\tconst task = change.fullDocument;\n\t\n\t\t\t\tif (task) {\n\t\t\t\t\tif (this._workerTasks.length) {\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tthis.processTask(task);\n\t\t\t\t\t\t}, this._workerTasks.length * 50);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.processTask(task);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\n\t\tchangeStream.on('error', (error) => {\n\t\t\tconsole.error('Error in change stream worker task requests:', error);\n\t\t\tchangeStream.close();\n\t\t\tsetTimeout(() => this.startWorkerInstance(), 5000); // Restart after a delay\n\t\t});\n\t\n\t\tchangeStream.on('close', () => {\n\t\t\tconsole.log('Change stream worker task requests closed. Restarting...');\n\t\t\tsetTimeout(() => this.startWorkerInstance(), 5000); // Restart after a delay\n\t\t});\n\n\t\t// First, process any existing pending tasks in the database\n\t\tconst pendingTasks = await WorkerTaskRequests.find({ status: 'pending' }, {sort: {createdAt: 1}});\n\n\t\tfor (const task of pendingTasks) {\n\t\t\tconsole.log('Processing existing pending task:', task._id);\n\t\t\tawait this.processTask(task);\n\t\t}\n\t}\n\t\n\t// Process a task (handles both existing and new tasks)\n\tprivate async processTask(task) {\n\t\t// Update the task status to 'processing'\n\t\tWorkerTaskRequests.updateOne({ _id: task._id, status: 'pending' }, { $set: { status: 'processing' } }).then(async resReq => {\n\t\t\tif (resReq) {\n\t\t\t\tthis._workerTasks.push(task._id);\n\n\t\t\t\ttry {\n\t\t\t\t\t// Run the actual method\n\t\t\t\t\tconst result = await this._methodManager.callMethodInternal.call(Object.assign({}, this._methodManager, { id_user: task.id_user, user: task.user, id_ws: task.id_ws }), task.method, ...task.params);\n\n\t\t\t\t\tif (this._workerTasks.includes(task._id)) {\n\t\t\t\t\t\tthis._workerTasks.splice(this._workerTasks.indexOf(task._id), 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tWorkerTaskResponses.create({\n\t\t\t\t\t\tid_request: task._id,\n\t\t\t\t\t\thas_error: false,\n\t\t\t\t\t\tdata: result,\n\t\t\t\t\t\tid_user: task.id_user,\n\t\t\t\t\t\tuser: task.user,\n\t\t\t\t\t\tid_ws: task.id_ws\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\tconsole.error('Worker failed to process task:', task._id, err);\n\n\t\t\t\t\tif (this._workerTasks.includes(task._id)) {\n\t\t\t\t\t\tthis._workerTasks.splice(this._workerTasks.indexOf(task._id), 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tWorkerTaskResponses.create({\n\t\t\t\t\t\tid_request: task._id,\n\t\t\t\t\t\thas_error: true,\n\t\t\t\t\t\tdata: err.message,\n\t\t\t\t\t\tid_user: task.id_user,\n\t\t\t\t\t\tuser: task.user,\n\t\t\t\t\t\tid_ws: task.id_ws\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Mark the task as complete\n\t\t\t\tWorkerTaskRequests.updateOne({ _id: task._id }, { $set: { status: 'complete' } });\n\t\t\t}\n\t\t}, () => {});\n\t}\n\n\tprivate safeShutdown() {\n\t\tif (!this._safeShutdown) {\n\t\t\tconsole.log(new Date(), 'Safe Shutdown Command Received');\n\t\t}\n\n\t\tif (\n\t\t\t!this._monitorManagerFunction.getActiveMonitorFunctions().length && \n\t\t\t// (!this._monitorManagerFunction.getLastCompletedMonitorFunction() ||\n\t\t\t// Date.now() >= this._monitorManagerFunction.getLastCompletedMonitorFunction().endTime.getTime() + 1500) &&\n\t\t\t!this._msgQueue.length &&\n\t\t\t!this._msgQueueRunning &&\n\t\t\t!this._offlineUpdates.length\n\t\t) {\n\t\t\tResolveIOServer.getMongoConnection().close(false).then(() => {\n\t\t\t\tconsole.log(new Date(), 'Safe Exit Complete, Process Exit');\n\t\t\t\tprocess.exit(0);\n\t\t\t}, () => {process.exit(1)});\n\t\t}\n\t\telse {\n\t\t\tif (!this._safeShutdown) {\n\t\t\t\tthis._safeShutdown = true;\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._safeShutdown = false;\n\t\t\t\t}, 1000);\n\n\t\t\t\tconsole.log(new Date(), \n\t\t\t\t\t'Safe Exit In Progress', \n\t\t\t\t\tthis._monitorManagerFunction.getActiveMonitorFunctions().length, \n\t\t\t\t\t// this._monitorManagerFunction.getLastCompletedMonitorFunction() ? this._monitorManagerFunction.getLastCompletedMonitorFunction().endTime : '',\n\t\t\t\t\tthis._msgQueue.length, \n\t\t\t\t\tthis._msgQueueRunning,\n\t\t\t\t\tthis._offlineUpdates.length\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsetImmediate(() => {\n\t\t\t\tthis.safeShutdown();\n\t\t\t});\n\t\t}\n\t}\n\n\tgetIsWorkersEnabled() {\n\t\treturn this._isWorkersEnabled;\n\t}\n\n\tgetIsWorkerInstance() {\n\t\treturn this._isWorkerInstance;\n\t}\n\n\tpublic getWS(id_ws: string) {\n\t\treturn Array.from(this._serverWSS.clients).filter(a => a['id_socket'] === id_ws)[0];\n\t}\n\n\tpublic getWSList() {\n\t\tlet res = [];\n\n\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\tres.push(ws['id_socket']);\n\t\t});\n\n\t\treturn res;\n\t}\n\n\tpublic getWSUserList() {\n\t\tlet res = [];\n\n\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\tres.push(ws['id_user']);\n\t\t});\n\n\t\treturn res;\n\t}\n\n\tpublic getHTTPServer() {\n\t\treturn this._serverHTTP;\n\t}\n\n\tpublic getCronManager() {\n\t\treturn this._cronManager;\n\t}\n\n\tpublic getMethodManager() {\n\t\treturn this._methodManager;\n\t}\n\n\tpublic getSubscriptionManager() {\n\t\treturn this._subscriptionManager;\n\t}\n\n\tpublic getMonitorManager() {\n\t\treturn this._monitorManager;\n\t}\n\n\tpublic getRebootFlag() {\n\t\treturn this._rebootFlag;\n\t}\n\n\tprivate createServer(): void {\n\t\t// Start express server\n\t\tthis._serverHTTP = createServer(this._app);\n\t\tthis._serverHTTP.keepAliveTimeout = 65000;\n\t\tthis._serverHTTP.headersTimeout = 66000; // This should be bigger than `keepAliveTimeout + your server's expected response time`\n\n\t\t// Start websocket server\n\t\t// Verify client with token before opening socket\n\t\tthis._serverWSS = new WebSocket.Server({ \n\t\t\tport: this._portWSS,\n\t\t\tverifyClient: this.publicProgram ? null : async (info, cb) => {\n\t\t\t\tif (this._rebootFlag) {\n\t\t\t\t\tcb(false, 409, 'Unable To Process');\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\t\t\tconsole.log('Verify Client', info, cb);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet infoData = (<string>info.req.headers['sec-websocket-protocol']).split(/,/);\n\n\t\t\t\t\tif (info.origin !== this._serverConfig['ROOT_URL'] && info.origin !== this._serverConfig['SEC_ROOT_URL'] && info.origin !== this._serverConfig['RESOLVEIO_URL'] && info.origin !== this._serverConfig['RESOLVEIO_SECONDARY_URL']) {\n\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet token = infoData[0];\n\t\t\t\t\t\tif (!token) {\n\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tjwt.verify(token, this._serverConfig['JWT_SECRET'], async (err, decoded) => {\n\t\t\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\t\t\tcb(false, 401, 'Unauthorized');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tinfo.req['id_user'] = decoded['id_user'];\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tlet user = await Users.findById(decoded['id_user']);\n\t\t\t\t\t\t\t\t\t\tif (user) {\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['user'] = user.fullname;\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['user_readonly'] = user.readonly || false;\n\t\t\t\t\t\t\t\t\t\t\tinfo.req['doc_user'] = user;\n\t\t\t\t\t\t\t\t\t\t\tcb(true);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\t\tcb(false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t\t\t\t\tcb(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t// Listen to port for websocket\n\tprivate listen(): void {\n\t\tthis._serverHTTP.listen(this._portHTTP, () => {\n\t\t\tconsole.log('Running server on port %s', this._portHTTP);\n\t\t});\n\n\t\tthis._serverWSS.on('listening', () => {\n\t\t\tconsole.log('Running server on port %s', this._portWSS);\n\t\t});\n\n\t\t// On websocket connection (already verified)\n\t\tthis._serverWSS.on('connection', (ws, req) => {\n\t\t\tif (!this.publicProgram) {\n\t\t\t\t// Get user from token\n\t\t\t\tws['id_user'] = req['id_user'];\n\t\t\t\tws['user'] = req['user'];\n\t\t\t\tws['user_readonly'] = req['user_readonly'];\n\t\t\t\tws['doc_user'] = req['doc_user'];\n\n\t\t\t\tif (ws['user'] !== 'Admin' && this._serverConfig['CLIENT_NAME'] !== 'ResolveIO') {\n\t\t\t\t\tthis.getMethodManager().callMethodInternal.call(this.getMethodManager(), 'supportCreateBillingUser', {\n\t\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\t\tuser: ws['user'],\n\t\t\t\t\t\tdate: new Date(),\n\t\t\t\t\t\tclient: ResolveIOServer.getClientName()\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tws['id_socket'] = objectIdHexString();\n\t\t\tws['retryCnt'] = 0;\n\n\t\t\tthis._subscriptionManager.createLoggedInUser(ws['id_socket']).then(() => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\tws.ping(() => {});\n\t\t\t\t}, 5000);\n\t\t\t});\n\n\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\tconsole.log('Connection from: ' + req['user']);\n\t\t\t}\n\t\t\t\n\t\t\t// Use for keeping connection alive (ping/pong)\n\t\t\tws['isAlive'] = true;\n\t\t\tws.on('pong', () => {\n\t\t\t\tws['isAlive'] = true;\n\t\t\t\tws['pongTime'] = new Date();\n\t\t\t\tws['latency'] = moment.duration(moment(ws['pongTime']).diff(ws['pingTime'])).asMilliseconds();\n\t\t\t\tthis._subscriptionManager.loggedInLatency(ws);\n\t\t\t})\n\t\t\t.on('message', async (message: string) => {\n\t\t\t\tif (this.LOGGER === 'DEBUG') {\n\t\t\t\t\tconsole.log('Message from: ' + ws['user'], message);\n\t\t\t\t}\n\n\t\t\t\tthis._debugMsgRecv += 1;\n\n\t\t\t\tlet parseErrorFound = false;\n\n\t\t\t\tlet socketData = [];\n\t\t\t\t\n\t\t\t\ttry {\n\t\t\t\t\tsocketData = JSON.parse(message, dateReviver);\n\t\t\t\t}\n\t\t\t\tcatch(e) {\n\t\t\t\t\tconsole.log('Error - JSON.parse', message);\n\t\t\t\t\t\n\t\t\t\t\tthis._methodManager.sendEmail('dev@resolveio.com', 'SERVER - JSON Parse Error - ' + this._serverConfig['CLIENT_NAME'], JSON.stringify([message, e]));\n\n\t\t\t\t\tparseErrorFound = true;\n\t\t\t\t}\n\n\t\t\t\tif (!parseErrorFound) {\n\t\t\t\t\tif (socketData[0] === 'ping') {\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tws.send('pong', (error) => {\n\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Pong');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet messageRoute = socketData[0];\n\n\t\t\t\t\tif (!this.publicProgram && this._clientRoutes.some(a => messageRoute.includes(a)) && !ws['doc_user'].roles.groups.some(a => a.views.some(b => messageRoute.includes(b) || b.includes(messageRoute))) && !ws['doc_user'].roles.super_admin) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet messageDate = socketData[1];\n\t\t\t\t\tlet messageId = socketData[2]\n\t\t\t\t\tlet type = socketData[3]\n\n\t\t\t\t\tif (type === 'subscription') {\n\t\t\t\t\t\tlet subType = socketData[4];\n\t\t\t\t\t\tlet pub = socketData[5];\n\t\t\n\t\t\t\t\t\t// Subscribe\n\t\t\t\t\t\tif (subType === 'sub') {\n\t\t\t\t\t\t\tthis._subscriptionManager.subscribe(messageRoute, messageDate, ws, messageId, pub, socketData.slice(6));\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Unsubscribe\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis._subscriptionManager.unsubscribe(messageRoute, messageDate, ws, messageId, pub, socketData.slice(6));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (!this.publicProgram && type === 'offline') {\n\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\tdata: 'ACK'\n\t\t\t\t\t\t};\n\t\t\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tws.send(JSON.stringify(serverRes), (error) => {\n\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Offline Ack Main');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._offlineUpdates.push(ws);\n\t\t\t\t\t\tlet offlineUpdates = socketData[4];\n\n\t\t\t\t\t\tfor (let i = 0; i < offlineUpdates.length; i++) {\n\t\t\t\t\t\t\tlet update = offlineUpdates[i];\n\t\t\t\t\t\t\tlet data = update.data;\n\n\t\t\t\t\t\t\tlet serverResMethod: ServerResponseModel = {\n\t\t\t\t\t\t\t\tmessageId: update.data[2],\n\t\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\t\tdata: 'ACK'\n\t\t\t\t\t\t\t};\n\t\t\t\n\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\tws.send(JSON.stringify(serverResMethod), (error) => {\n\t\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Server App', 'Error WS Offline Ack Each');\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlet updateRoute = data.shift();\n\t\t\t\t\t\t\tlet updateDate = data.shift();\n\t\t\t\t\t\t\tlet updateMessageId = data.shift();\n\t\t\t\t\t\t\tlet updateType = data.shift();\n\t\t\t\t\t\t\tlet method = data.shift();\n\t\t\t\t\t\t\tlet methodLatencyId = objectIdHexString();\n\n\t\t\t\t\t\t\tLogMethodLatencies.create({\n\t\t\t\t\t\t\t\t_id: methodLatencyId,\n\t\t\t\t\t\t\t\t__v: 0,\n\t\t\t\t\t\t\t\tdate_start: new Date(),\n\t\t\t\t\t\t\t\tdate_end: null,\n\t\t\t\t\t\t\t\tlatency_ms: 0,\n\t\t\t\t\t\t\t\tmethod: method\n\t\t\t\t\t\t\t});\n\t\t\t\n\t\t\t\t\t\t\tif (method !== 'reportBuilderGetResults' && method !== 'reportBuilderGetDistinctValue' && method !== 'reportBuilderBuildTree' && method !== 'generatePDF' && method !== 'getWOOfflineData' && method !== 'countQuery' && method !== 'countWithQuery' && method !== 'countCollectionWithQuery' && method !== 'find' && method !== 'findOne' && method !== 'findWithOptions' && method !== 'getDrivers' && method !== 'processAirdropDistribution') {\n\t\t\t\t\t\t\t\tLogs.insertOne({\n\t\t\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(data)) < 200000 ? JSON.stringify(data, null, 2) : 'Too Big',\n\t\t\t\t\t\t\t\t\tmethod: method,\n\t\t\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\t\t\troute: messageRoute\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (this._methodManager._methods[method]) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait this._methodManager.callMethodInternal.call(Object.assign({}, this._methodManager, {id_user: ws['id_user'], user: ws['user'], id_ws: ws['id_socket']}), method, ...data);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t\t\t\tconsole.log(new Date(), 'Offline Error', JSON.stringify(err, null, 2));\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (method === 'updateDocumentOffline' || method === 'updateDocumentPropsOffline') {\n\t\t\t\t\t\t\t\t\tResolveIOServer.getMongoManager().invalidateQueryCache(data[0]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tconsole.log('Offline - Could not find method: ' + method);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._offlineUpdates.splice(this._offlineUpdates.map(a => a['id_socket']).indexOf(ws['id_socket']), 1);\n\t\t\t\t\t}\n\t\t\t\t\telse { //methods\n\t\t\t\t\t\tthis._msgQueue.splice(0, 0, {\n\t\t\t\t\t\t\tws: ws,\n\t\t\t\t\t\t\tdata: socketData\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('end', () => {\n\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\tconsole.log(new Date(), 'Server App', 'WS End');\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('close', () => {\n\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\tconsole.log(new Date(), 'Server App', 'WS Close');\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('error', error => {\n\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\t\t\tconsole.log(new Date(), ws['user'], ws['id_socket'], 'WS Error');\n\t\t\t\t}\n\t\t\t\t\n\t\t\t});\n\t\t});\n\n\t\t// Keep alive timer to ping/pong\n\t\tsetInterval(() => {\n\t\t\tthis._serverWSS.clients.forEach((ws: WebSocket) => {\n\t\t\t\tif (ws['pingTime'] && Date.now() - ws['pingTime'].getTime() >= 20000) {\n\t\t\t\t\tif (ws['isAlive'] === false) {\n\t\t\t\t\t\tws['retryCnt']++;\n\n\t\t\t\t\t\tif (ws['retryCnt'] >= 3) {\n\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\t\tws.ping(() => {});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tws['retryCnt'] = 0;\n\t\t\t\t\t\tws['isAlive'] = false;\n\t\t\t\t\t\tws['pingTime'] = new Date();\n\t\t\t\t\t\tws.ping(() => {});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}, 20000);\n\n\t\tsetInterval(() => {\n\t\t\tif (!this._msgQueueRunning) {\t\t\t\t\n\t\t\t\tif (this._msgQueue.length) {\n\t\t\t\t\tthis._msgQueueRunning = true;\n\t\t\t\t\tthis._debugMsgQueue += 1;\n\n\t\t\t\t\tlet msg = this._msgQueue.pop();\n\t\t\t\t\tlet data = msg.data;\n\t\t\t\t\tlet ws = msg.ws;\n\t\t\n\t\t\t\t\tlet messageRoute: string = data.shift();\n\t\t\t\t\tlet messageDate: Date = data.shift();\n\t\t\t\t\tlet messageId: number = data.shift();\n\t\t\t\t\tlet type: string = data.shift();\n\t\t\n\t\t\t\t\t// Method call\n\t\t\t\t\tif (type === 'method') {\n\t\t\t\t\t\tlet method = data.shift();\n\n\t\t\t\t\t\tif (ws['user_readonly']) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet methodLatencyId = objectIdHexString();\n\n\t\t\t\t\t\tLogMethodLatencies.create({\n\t\t\t\t\t\t\t_id: methodLatencyId,\n\t\t\t\t\t\t\t__v: 0,\n\t\t\t\t\t\t\tdate_start: new Date(),\n\t\t\t\t\t\t\tdate_end: null,\n\t\t\t\t\t\t\tlatency_ms: 0,\n\t\t\t\t\t\t\tmethod: method\n\t\t\t\t\t\t});\n\t\t\n\t\t\t\t\t\tif (method !== 'reportBuilderGetResults' && method !== 'reportBuilderGetDistinctValue' && method !== 'reportBuilderBuildTree' && method !== 'generatePDF' && method !== 'getWOOfflineData' && method !== 'countQuery' && method !== 'countWithQuery' && method !== 'countCollectionWithQuery' && method !== 'find' && method !== 'findOne' && method !== 'findWithOptions' && method !== 'getDrivers' && method !== 'processAirdropDistribution') {\n\t\t\t\t\t\t\tLogs.insertOne({\n\t\t\t\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t\t\t\ttype: 'client-request',\n\t\t\t\t\t\t\t\tcollection: '',\n\t\t\t\t\t\t\t\tid_document: '',\n\t\t\t\t\t\t\t\tpayload: getBinarySize(JSON.stringify(data)) < 200000 ? JSON.stringify(data, null, 2) : 'Too Big',\n\t\t\t\t\t\t\t\tmethod: method,\n\t\t\t\t\t\t\t\tid_user: ws['id_user'] || '',\n\t\t\t\t\t\t\t\tuser: ws['user'] || '',\n\t\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\t\troute: messageRoute\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\n\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\tdata: 'ACK'\n\t\t\t\t\t\t};\n\t\t\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tws.send(JSON.stringify(serverRes), (error) => {\n\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\n\t\t\t\t\t\tif (this._methodManager._methods[method]) {\n\t\t\t\t\t\t\tthis._methodManager.callMethod(methodLatencyId, ws, messageDate, messageId, method, ...data);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tconsole.log('Could not find method: ' + method);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (type === 'methodResponse') {\n\t\t\t\t\t\tlet method = data.shift();\n\t\t\n\t\t\t\t\t\tMethodResponses.findOne({$and: [\n\t\t\t\t\t\t\t{id_user: ws['id_user']}, \n\t\t\t\t\t\t\t{message_id: messageId},\n\t\t\t\t\t\t\t{method: method},\n\t\t\t\t\t\t\t{date: messageDate}\n\t\t\t\t\t\t]}).then(res => {\n\t\t\t\t\t\t\tif (res) {\n\t\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\t\tws.send(JSON.stringify(res.response), (error) => {\n\t\t\t\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\t\t\t\tthis.unsubscribeWS(ws);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, err => {});\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tthis._msgQueueRunning = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}, 1);\n\t}\n\n\tpublic unsubscribeWS(ws: WebSocket) {\n\t\tif (this._subscriptionManager.getEnableDebug()) {\n\t\t\tconsole.log(new Date(), 'Server App', 'Unsub WS', ws['user'], ws['id_socket']);\n\t\t}\n\t\tthis._subscriptionManager.unsubscribeAll(ws);\n\t\tws.removeAllListeners();\n\t\tws = null;\n\t}\n\n\tpublic getApp() {\n\t\treturn this._app;\n\t}\n\n\tpublic getServerConfig() {\n\t\treturn this._serverConfig;\n\t}\n}"]}