valence-connect
Version:
Connect to Valence for requests coming from applications running in the Valence Portal
1 lines • 7.36 kB
JavaScript
;const request=require("request"),fs=require("fs"),urlParse=require("url-parse"),http=require("http"),winston=require("winston"),jsonfile=require("jsonfile");class ValenceConnect{constructor(){const e=this;e.connectUrl=null,e.connectKey=null,e.configured=!1,e.baseErrorLabel="Valence Connect [method] : ",e.availableLanguages=["en","de","es","fr","it","ja","nl","pl","ru"],e.IBMi=!1,e.logging=!1,e.defaultLanguage="en",e.sidStorage=require("node-persist"),e.sidStorageTimeToLive=288e5,e.baseInit(),e.locale={en:require("../locale/en"),de:require("../locale/de"),es:require("../locale/es"),fr:require("../locale/fr"),it:require("../locale/it"),ja:require("../locale/ja"),nl:require("../locale/nl"),pl:require("../locale/pl"),ru:require("../locale/ru")},e.lang={lit:getLiteral.bind(e)}}async baseInit(){await this.sidStorage.init()}init(e){const t=this;return t.isEmpty(e)||t.isEmpty(e.defaultLanguage)||-1===t.availableLanguages.indexOf(e.defaultLanguage)||(t.defaultLanguage=e.defaultLanguage),t.lang={lit:getLiteral.bind(t)},new Promise((s,n)=>{let i=!1,r="";const o=e=>{i=!0,e=t.getErrorLabel("init")+e,t.isEmpty(r)?r=e:r+="\n"+e},a=()=>{winston.log("error",t.lang.lit("ERROR")+" - "+t.getErrorLabel("init")+t.lang.lit("connectionNotConfigured")),writeErrorFile.bind(t)(r).then(()=>{n()})},c=()=>{if(t.isEmpty(e))o(t.lang.lit("urlRequired")),a();else{const n=urlParse(e.url,!0);(t.isEmpty(e.url)||t.isEmpty(n.query)||t.isEmpty(n.query.key))&&o(t.lang.lit("invalidWebServiceUrl")),t.isEmpty(e.IBMi)||!0!==e.IBMi||(t.IBMi=!0),i?a():(t.connectUrl=n.origin+n.pathname,t.connectKey=n.query.key,t.configured=!0,t.isEmpty(e.logging)||(t.logging=e.logging),s())}};if(t.isEmpty(e)){const s=__dirname.indexOf("node_modules");let n;if(n=-1!==s?__dirname.substring(0,s)+"valence.json":"./valence.json",!t.isEmpty(n))return void jsonfile.readFile(n,function(t,s){t||(e=s),c()})}c()})}dbQuery(e,t,s){const n=this;return new Promise((i,r)=>{const o=e instanceof http.IncomingMessage?n.getParams(e):e||{},a=e=>{r({success:!1,msg:n.getErrorLabel.bind(n)("dbQuery")+e.message})},c=e=>{!n.isEmpty(t)&&t instanceof http.ServerResponse&&569==e.resp.statusCode?t.status(569).json(e.body):i(e.body)};n.isEmpty(s)?r({success:!1,msg:n.lang.lit("sqlStatementRequired")}):n.processRequest(Object.assign(o,{action:"dbQuery",stmt:s})).then(c).catch(a)})}decodeUTF16(e){try{return e=e.replace(/([A-Fa-f0-9]{4})/g,function(e,t){let s="",n=parseInt(t,16);return n<=65535?s+=String.fromCharCode(n):n<=1114111?(n-=65536,s+=String.fromCharCode(55296|n>>10)+String.fromCharCode(56320|1023&n)):s+="hex2Char error: Code point out of range: "+(n+0).toString(16).toUpperCase(),s})}catch(t){return e}}getErrorLabel(e){return this.baseErrorLabel.replace("method",e)}getParams(e,t){const s={};if(this.isEmpty(e.query)||Object.assign(s,e.query),this.isEmpty(e.body)||Object.assign(s,e.body),!this.isEmpty(t)){let e;for(const n in s)if(n===t){e=s[n];break}return e}return s}getSessionInformation(e){const t=this;return new Promise((s,n)=>{getInfo.bind(t)("getSessionInformation",e).then(e=>{s(e)}).catch(e=>{n(e)})})}getSettings(e,t,s){const n=this;return new Promise((i,r)=>{getInfo.bind(n)("getSettings",e,"_settings",s).then(e=>{const s=e.settings;if(n.isEmpty(t))i(s);else{const e=[];for(const n of s)if(-1!==t.indexOf(n.name)&&(e.push(n),e.length===t.length))break;i(e)}}).catch(e=>{r(e)})})}getUserInformation(e,t){const s=this;return new Promise((n,i)=>{getInfo.bind(s)("getUserInformation",e,"_user",t).then(e=>{n(e)}).catch(e=>{i(e)})})}invalidSession(e){e.status(569).json({hdr:"invalidSession",body:"sessionEnded",action:"LOGOUT",success:!1})}isAuthenticated(e,t){const s=this,n=s.getParams(e);return new Promise(i=>{if(s.logging){const n=t.json.bind(t),i=Date.now(),r=r=>{const o=Date.now()-i;logIt.bind(s)(e,t,r,o),n(r)};t.json=r}s.processRequest({action:"isAuthenticated",sid:n.sid}).then(e=>{s.isEmpty(e.body)||"object"!=typeof e.body?s.invalidSession(t):"sessionInvalid"===e.body||!s.isEmpty(e.body.success)&&!e.body.success?s.invalidSession(t):i()}).catch(e=>{t.json({success:!1,msg:s.getErrorLabel("isAuthenticated")+e.message})})})}isEmpty(e){return null==e||""===e||"[object Array]"===toString.call(e)&&0===e.length}prepareRequest(e){const t=this;return new Promise((s,n)=>{if(t.isEmpty(e))n({message:t.lang.lit("parametersRequired")});else{const i=e.sid,r=t.connectUrl,o={};t.isEmpty(i)?n({invalidSid:!0}):(Object.assign(o,{key:t.connectKey,session:e.sid}),delete e.sid,Object.assign(o,e),s({url:r,params:o}))}})}processRequest(e){const t=this;return new Promise((s,n)=>{const i=e=>{n({success:!1,message:e})},r=e=>{request(e.url,{method:"POST",form:e.params,json:!0},(e,n,r)=>{t.isEmpty(e)?s({resp:n,body:r}):i(e.message)})},o=e=>{e.invalidSid?i(t.lang.lit("sessionIdRequired")):i(e.message)};isConfigured.bind(t)()?t.prepareRequest(e).then(r).catch(o):i(t.lang.lit("connectionNotConfigured"))})}}async function getInfo(e,t,s,n){const i=this;return(i.isEmpty(n)||"boolean"!=typeof n)&&(n=!1),new Promise(async(r,o)=>{const a=t+s,c=!i.isEmpty(s),l=t=>{o({success:!1,msg:i.getErrorLabel(e)+t.message})},g=e=>{const t={};i.processRequest(e).then(e=>{Object.assign(t,i.getParams(e.resp)),t.success&&c?setSidStorage.bind(i)(a,t).then(()=>{u(t)}).catch(l):u(t)}).catch(e=>{l({message:e.message})})},u=e=>{r(Object.assign({success:!0},e))};if(c&&n&&await i.sidStorage.removeItem(a),c){const s=s=>{i.isEmpty(s)?g({action:e,sid:t}):u(JSON.parse(s))};getSidStorage.bind(i)(a).then(s).catch(l)}else g({action:e,sid:t})})}function getLiteral(e,t){const s=this;let n=s.defaultLanguage;if(!s.isEmpty(t))if("string"==typeof t)-1!==s.availableLanguages.indexOf(t)&&(n=t);else{const e=s.getParams(t,"lang");s.isEmpty(e)||-1===s.availableLanguages.indexOf(e)||(n=e)}return s.locale[n][e]}function getSidStorage(e){const t=this;return new Promise((s,n)=>{t.isEmpty(e)?n("key not passed"):getSessionStorage.bind(t)(e).then(e=>{s(e)})})}async function getSessionStorage(e){return await this.sidStorage.getItem(e)}function isConfigured(){let e=!0;return this.isEmpty(this.connectUrl)&&(e=!1),e}function logIt(e,t,s,n){const i=this;return new Promise(t=>{const r=i.getParams(e),o={action:"addLogEntry",duration:n,url:e.url,appId:r.app,sid:r.sid,post:JSON.stringify(r),response:JSON.stringify(s)},a=e.url.indexOf("?");-1!==a&&Object.assign(o,{url:e.url.substring(0,a)}),i.processRequest(o),t()})}function preSidStorage(e,t){const s=this;return new Promise(n=>{if(s.isEmpty(e))n(t);else{const i=e.indexOf("_");if(-1!==i){const n=e.substring(i+1);if("settings"===n&&s.IBMi){if("[object Array]"===toString.call(t.settings))for(const e of t.settings)e.value=s.decodeUTF16(e.value)}else if("user"===n){const e=["loginId","firstName","midInit","lastName","userDesc"];for(const n in t)-1!==e.indexOf(n)&&(t[n]=s.decodeUTF16(t[n]))}}n(t)}})}function setSidStorage(e,t){const s=this;return new Promise((n,i)=>{preSidStorage.bind(s)(e,t).then(t=>{if(s.isEmpty(e))i("key not passed");else{const r=r=>{s.isEmpty(r)?n(e,t):i(r)};setSessionStorage.bind(s)(e,t).then(()=>{r()}).catch(e=>{r(e)})}})})}async function setSessionStorage(e,t){await this.sidStorage.setItem(e,JSON.stringify(t),{ttl:this.sidStorageTimeToLive})}function writeErrorFile(e){return new Promise(t=>{const s=Date.now();fs.writeFile(__dirname+"/valence-error-log-"+s+".txt",e,()=>{process.exit(),t()})})}module.exports=new ValenceConnect;