UNPKG

jsharmony-factory

Version:
345 lines (304 loc) 15.5 kB
/* Copyright 2017 apHarmony This file is part of jsHarmony. jsHarmony is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. jsHarmony is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this package. If not, see <http://www.gnu.org/licenses/>. */ var path = require('path'); var _ = require('lodash'); var jsHarmony = require('jsharmony'); var jsHarmonyModule = require('jsharmony/jsHarmonyModule'); var jsHarmonySite = require('jsharmony/jsHarmonySite'); var jsHarmonyRouter = require('jsharmony/jsHarmonyRouter'); var Helper = jsHarmony.lib.Helper; var cookieParser = require('cookie-parser'); var jsHarmonyFactoryConfig = require('./jsHarmonyFactoryConfig.js'); var jsHarmonyFactoryJobProc = require('./models/_jobproc.js'); var agreement = require('./models/_agreement.js'); var menu = require('./models/_menu.js'); var help = require('./models/_help.js'); var funcs = require('./models/_funcs.js'); var jsHarmonyFactoryTransform = require('./jsHarmonyFactoryTransform.js'); function jsHarmonyFactory(name, options){ options = _.extend({ mainSiteID: 'main', clientSiteID: 'client', clientPortal: false, schema: 'jsharmony' }, options); var _this = this; jsHarmonyModule.call(this, name); if(name) _this.name = name; _this.Config = new jsHarmonyFactoryConfig(); _this.typename = 'jsHarmonyFactory'; _this.mainSiteID = options.mainSiteID; _this.clientSiteID = options.clientSiteID; _this.clientPortal = options.clientPortal; _this.schema = options.schema; _this.mainRouter = null; _this.clientRouter = null; _this.funcs = new funcs(_this); _this.transform = new jsHarmonyFactoryTransform(_this); //_this.transform.Add(require('./jsHarmonyFactoryTransform.Classic.js')); _this.onCreateServer = []; //function(server){} _this.onFilterSQLScripts = function(fileObj){ if(fileObj.name.substr(0,5)=='cust.'){ if(!_this.clientPortal) return false; } }; } jsHarmonyFactory.prototype = new jsHarmonyModule(); jsHarmonyFactory.Application = function(options){ return (new jsHarmonyFactory(null,options)).Application(); }; jsHarmonyFactory.prototype.onModuleAdded = function(jsh){ var _this = this; //CREATE SITES in JSH if(!(_this.mainSiteID in jsh.Sites)) jsh.Sites[_this.mainSiteID] = new jsHarmonySite.Placeholder(); if(_this.clientPortal && !(_this.clientSiteID in jsh.Sites)) jsh.Sites[_this.clientSiteID] = new jsHarmonySite.Placeholder(); }; jsHarmonyFactory.prototype.Init = function(cb){ var _this = this; if(typeof _this.Config.auto_start_job_processor == 'undefined') _this.Config.auto_start_job_processor = !_this.jsh.Config.interactive; this.jsh.SetJobProc(new jsHarmonyFactoryJobProc(this, _this.jsh.DB['default'])); if(_this.clientPortal){ var prevClientConfig = this.jsh.Sites[_this.clientSiteID]; if(prevClientConfig && prevClientConfig.initialized) throw new Error('jsHarmony Factory could not initialize site "'+_this.clientSiteID+'": Already initialized'); this.jsh.Sites[_this.clientSiteID] = new jsHarmonySite(_this.jsh, _this.clientSiteID, _this.GetDefaultClientConfig()); this.jsh.Sites[_this.clientSiteID].Merge(prevClientConfig); } var prevMainConfig = this.jsh.Sites[_this.mainSiteID]; if(prevMainConfig && prevMainConfig.initialized) throw new Error('jsHarmony Factory could not initialize site "'+_this.mainSiteID+'": Already initialized'); this.jsh.Sites[_this.mainSiteID] = new jsHarmonySite(_this.jsh, _this.mainSiteID, _this.GetDefaultMainConfig()); this.jsh.Sites[_this.mainSiteID].Merge(prevMainConfig); var mainSite = this.jsh.Sites[_this.mainSiteID]; var clientSite = this.jsh.Sites[_this.clientSiteID]; if(typeof _this.jsh.Config.server.https_port == 'undefined'){ if(mainSite && mainSite.auth && (typeof mainSite.auth.allow_insecure_http_logins === 'undefined')) mainSite.auth.allow_insecure_http_logins = true; if(clientSite && clientSite.auth && (typeof clientSite.auth.allow_insecure_http_logins === 'undefined')) clientSite.auth.allow_insecure_http_logins = true; } this.jsh.AppSrv.modelsrv.srcfiles['jsHarmonyFactory.SuggestFeature'] = this.jsh.getEJS('jsHarmonyFactory.SuggestFeature'); _this.jsh.Config.server.add_default_routes = false; this.jsh.CreateServer(_this.jsh.Config.server, function(server){ _this.jsh.Servers['default'] = server; var app = _this.app = _this.jsh.Servers['default'].app; Helper.trigger(_this.onCreateServer, server); _this.VerifyConfig(); app.use(jsHarmonyRouter.PublicRoot(path.join(__dirname, 'public'))); if(_this.clientPortal){ app.get(/^\/client$/, function (req, res, next) { res.redirect('/client/'); }); app.use('/client', cookieParser(_this.Config.clientcookiesalt, { path: '/client/' })); app.all('/client/login', function (req, res, next) { req._override_basetemplate = 'public'; req._override_title = 'Customer Portal Login'; next(); }); app.all('/client/login/forgot_password', function (req, res, next) { req._override_basetemplate = 'public'; next(); }); app.all('/client/logout', function (req, res, next) { req._override_basetemplate = 'public'; next(); }); _this.clientRouter = jsHarmonyRouter(_this.jsh, _this.clientSiteID); _this.clientRouter.get('*', function(req, res, next){ _this.jsh.Gen404(req, res); return; }); app.use('/client', _this.clientRouter); } app.use('/', cookieParser(_this.Config.maincookiesalt, { path: '/' })); app.all('/login', function (req, res, next) { req._override_basetemplate = 'public'; req._override_title = 'Login'; next(); }); app.all('/login/forgot_password', function (req, res, next) { req._override_basetemplate = 'public'; next(); }); app.all('/logout', function (req, res, next) { req._override_basetemplate = 'public'; next(); }); _this.mainRouter = jsHarmonyRouter(_this.jsh, _this.mainSiteID); app.use('/', _this.mainRouter); _this.jsh.Servers['default'].addDefaultRoutes(); if(cb) return cb(); }); }; jsHarmonyFactory.prototype.Run = function(onComplete){ this.jsh.Servers['default'].Run(onComplete); if(this.Config.auto_start_job_processor) this.jsh.AppSrv.JobProc.Run(); }; jsHarmonyFactory.prototype.GetDefaultMainConfig = function(){ var _this = this; /******************* *** MAIN SYSTEM *** *******************/ var jshconfig_main = { basetemplate: 'index', baseurl: '/', publicurl: '/', show_system_errors: true, title: _this.Config.mainsitetitle, auth: { salt: _this.Config.mainsalt, supersalt: _this.Config.mainsalt, sql_auth: 'main_sql_auth', sql_login: 'main_sql_login', sql_superlogin: 'main_sql_superlogin', sql_loginsuccess: 'main_sql_loginsuccess', sql_passwordreset: 'main_sql_passwordreset', getuser_name: function (user_info, jsh) { return user_info[jsh.map.user_firstname] + ' ' + user_info[jsh.map.user_lastname]; }, getContextUser: function (user_info, jsh) { return 'S' + user_info[jsh.map.user_id]; } }, menu: menu(_this).bind(null, 'S'), help: help.bind(_this), globalparams: { 'barcode_server': _this.Config.barcode_settings.server, 'scanner_server': _this.Config.scanner_settings.server, 'user_id': function (req) { return req.user_id; }, 'user_name': function (req) { return req.user_name; }, 'help_view': function (req) { return _this.getHelpView(req); }, 'app_name': _this.jsh.Config.app_name, }, onLoad: function (jsh) { } }; jshconfig_main.private_apps = [ { '/_funcs/LOG_DOWNLOAD': _this.funcs.LOG_DOWNLOAD, '/_funcs/LOG': _this.funcs.LOG, '/_funcs/SUGGEST_FEATURE': _this.funcs.SUGGEST_FEATURE, '/_funcs/DEV_DB_SCRIPTS': _this.funcs.DEV_DB_SCRIPTS, '/_funcs/DEV_DB_OBJECTS': _this.funcs.DEV_DB_OBJECTS, '/_funcs/DEV_DB_UPGRADE': _this.funcs.DEV_DB_UPGRADE, '/_funcs/DEV_DB_DIFF': _this.funcs.DEV_DB_DIFF, '/_funcs/DEV_DB_SCHEMA': _this.funcs.DEV_DB_SCHEMA, '/_funcs/DEV_MODELS': _this.funcs.DEV_MODELS, '/_funcs/DEV_EMAILTEST': _this.funcs.DEV_EMAILTEST, } ]; return jshconfig_main; }; jsHarmonyFactory.prototype.GetDefaultClientConfig = function(){ var _this = this; var jsh = this.jsh; /************** *** CLIENT *** **************/ var jshconfig_client = { home_url: '/client/', basetemplate: 'client', baseurl: '/client/', publicurl: '/', show_system_errors: false, title: _this.Config.clientsitetitle, auth: { salt: _this.Config.clientsalt, supersalt: _this.Config.mainsalt, sql_auth: 'client_sql_auth', sql_login: 'client_sql_login', sql_superlogin: 'client_sql_superlogin', sql_loginsuccess: 'client_sql_loginsuccess', sql_passwordreset: 'client_sql_passwordreset', getuser_name: function (user_info, jsh) { return user_info[jsh.map.user_firstname] + ' ' + user_info[jsh.map.user_lastname]; }, getContextUser: function (user_info, jsh) { return 'C' + user_info[jsh.map.user_id]; }, onAuthComplete: function (req, user_info, jsh) { req.gdata = {}; req.gdata[jsh.map.client_id] = user_info[jsh.map.client_id]; req.gdata[jsh.map.client_name] = user_info[jsh.map.client_name]; req.gdata[jsh.map.client_agreement_tstmp] = user_info[jsh.map.client_agreement_tstmp]; req.gdata[jsh.map.client_overdue] = parseFloat(user_info[jsh.map.client_overdue]); req.gdata[jsh.map.client_overdue_ignore] = 0; }, }, menu: menu(_this).bind(null, 'C'), help: help.bind(_this), datalock: { /* jsh.map.client_id (below) */ }, datalocktypes: { /* jsh.map.client_id (below) */ }, globalparams: { 'user_id': function (req) { return req.user_id; }, 'user_name': function (req) { return req.user_name; }, 'company_id': function (req) { return req.gdata[jsh.map.client_id]; }, 'company_name': function (req) { return req.gdata[jsh.map.client_name]; }, 'barcode_server': _this.Config.barcode_settings.server, 'help_view': function (req) { return _this.getHelpView(req); }, 'app_name': 'Client Portal', } }; jshconfig_client.globalparams[jsh.map.client_id] = function (req) { return req.gdata[jsh.map.client_id]; }; jshconfig_client.globalparams[jsh.map.client_name] = function (req) { return req.gdata[jsh.map.client_name]; }; jshconfig_client.datalock[jsh.map.client_id] = function (req) { return req.gdata[jsh.map.client_id]; }; jshconfig_client.datalocktypes[jsh.map.client_id] = { 'name': jsh.map.client_id, 'type': 'bigint' }; var ignore_overdue_transaction = function (req, res, next) { if (req.gdata[jsh.map.client_overdue] <= 0) { return next(); } if (!('data' in req.body)) { return next(); } var data = JSON.parse(req.body.data); if (!(data instanceof Array)) { return next(); } var overdue_transaction = true; for (var i = 0; i < data.length; i++) { var action = data[i]; if ((action.model == 'C_PA_CC') || (action.model == 'C_PACC_PACCI') || (action.model == 'C_PACC_INFO')) continue; overdue_transaction = false; } if (overdue_transaction) req.gdata[jsh.map.client_overdue_ignore] = 1; next(); }; jshconfig_client.private_apps = [ { '/agreement/': agreement.form, '/agreement/_sign': agreement.sign, '*': agreement.check, '/agreement/welcome/': agreement.welcome }, { '/_d/_transaction/': ignore_overdue_transaction, '*': function (req, res, next) { if (req.gdata[jsh.map.client_overdue_ignore] > 0) return next(); if (req.gdata[jsh.map.client_overdue] > 0) { return Helper.Redirect302(res, req.baseurl + 'C_PA_CC/'); } next(); } } ]; return jshconfig_client; }; jsHarmonyFactory.prototype.getHelpView = function(req){ if(!this.Config.help_view) return null; if(_.isString(this.Config.help_view)) return this.Config.help_view; for(var siteid in this.Config.help_view){ if(req.jshsite.id==siteid) return this.Config.help_view[siteid]; } return ''; //throw new Error("help_view not defined in _config.json for '"+siteid+"' site"); }; jsHarmonyFactory.prototype.VerifyConfig = function(){ var _this = this; var jsh = _this.jsh; function verify_config(x, _caption) { if (!x || (_.isObject(x) && _.isEmpty(x))) { jsh.Log.error('*** Missing app.config.js setting: ' + _caption); return false; } return true; } var good_config = true; var required_fields = ['mainsalt', 'maincookiesalt']; if(_this.clientPortal) required_fields = required_fields.concat(['clientsalt', 'clientcookiesalt']); _.each(required_fields, function (val) { good_config &= verify_config(_this.Config[val], "config.modules['jsHarmonyFactory']." + val); }); if (!good_config) { jsh.Log.error('\r\n*** Invalid config, could not start server ***\r\n'); process.exit(1); } }; jsHarmonyFactory.prototype.addMainMenuItem = function(menu_id, menu_name, menu_desc, menu_cmd, menu_subcmd, menu_seq, roles){ var _this = this; if(!_this.Config.static_menu) throw new Error('static_menu not defined in module config'); if(!('main_menu' in _this.Config.static_menu)) _this.Config.static_menu.main_menu = []; var menu_item = { roles: roles }; menu_item[_this.transform.fields['menu_id']] = menu_id; menu_item[_this.transform.fields['menu_name']] = menu_name; menu_item[_this.transform.fields['menu_desc']] = menu_desc; menu_item[_this.transform.fields['menu_cmd']] = menu_cmd; menu_item[_this.transform.fields['menu_subcmd']] = menu_subcmd; menu_item[_this.transform.fields['menu_seq']] = menu_seq; _this.Config.static_menu.main_menu.push(menu_item); }; jsHarmonyFactory.prototype.addSubMenuItem = function(menu_id, menu_parent_name, menu_name, menu_desc, menu_cmd, menu_subcmd, menu_seq, roles){ var _this = this; if(!_this.Config.static_menu) throw new Error('static_menu not defined in module config'); if(!('sub_menu' in _this.Config.static_menu)) _this.Config.static_menu.sub_menu = []; var menu_item = { roles: roles }; menu_item[_this.transform.fields['menu_id']] = menu_id; menu_item[_this.transform.fields['menu_parent_name']] = menu_parent_name; menu_item[_this.transform.fields['menu_name']] = menu_name; menu_item[_this.transform.fields['menu_desc']] = menu_desc; menu_item[_this.transform.fields['menu_cmd']] = menu_cmd; menu_item[_this.transform.fields['menu_subcmd']] = menu_subcmd; menu_item[_this.transform.fields['menu_seq']] = menu_seq; _this.Config.static_menu.sub_menu.push(menu_item); }; exports = module.exports = jsHarmonyFactory;